Compare commits

...

15 Commits

Author SHA1 Message Date
Mike Griese
d2edb0a1ba port the changes over to main ; just the refactoring, none of the impl 2026-04-24 10:42:38 -05:00
Mike Griese
5b0e4b8acf just as I thought - we didn't actually need this 2026-04-24 06:27:00 -05:00
Mike Griese
d73b4e5022 Start by standing up a dummy type 2026-04-24 06:14:28 -05:00
Dustin L. Howett
17e6126597 spelling: move to v0.0.26 (#20099) 2026-04-23 19:37:41 +02:00
jason
7a83c0f167 Fix Korean IME overlay hiding characters to the right of cursor (#20041)
This commit fixes a regression in v1.24, where composing Korean text
in-between existing characters causes text to the right to be hidden.
This is problematic for the Korean IME, because it commonly inserts
the composed syllable between existing characters.

The fix compresses (removes/absorbs) available whitespace to the right
of the composition to make space for any existing text. This means
that a composition now virtually acts in insert mode.

Closes #20040
Refs #19738
Refs #20039

## Validation Steps Performed

1. Korean IME: compose `ㄷ` between `가` and `나` → display shows `가ㄷ나`,
`나` visible.
2. TUI box (vim prompt with padding): compose inside padded text box →
border preserved in place.
3. Composition at end of line (no chars to right): unaffected.
4. English and other IME input: not affected (no active composition
row).

Co-authored-by: jason <drvoss@users.noreply.github.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2026-04-16 19:12:19 -05:00
Carlos Zamora
b2666fb346 Fix local tests (#20120)
## Summary of the Pull Request
Fixes TabTests.cpp. Changes include:
- add `"closeOnExit": "never"` to some tests to avoid the race condition
discussed in #14623. It keeps the tabs/panes around so that we can
actually test them.
- removes the `assert(false)` in `TermControl::MinimumSize()`. I've been
hitting this assert in dev builds _every time_ I split a pane. I think
it isn't adding value, but if we want to investigate it further, we can.
- update MRU tests to not use the command palette (aka tab switcher) UI.
The UI requires you to hold a modifier key down to keep it displayed.
That isn't something we can simulate. Instead we just use the relevant
APIs to simulate switching tabs. This is ok because the `MRU` list is
still updated, so we're still able to validate that we're updating it
properly.
- Add `Tab[idx]` and `MRU[idx]` notation to MRU tests to make them
easier to follow

## Validation Steps Performed
 local tests pass

Closes #19610
Closes #14623
2026-04-15 22:24:13 +00:00
Carlos Zamora
8f4fdf9751 Normalize commandline in media resource tests (#20118)
## Summary of the Pull Request
Some of the Media Resource tests were failing on my machine. Turns out
that it's because my machine uses `C:\WINDOWS` instead of `C:\Windows`.

This PR fixes those tests by calling `Profile::NormalizeCommandline()`
on a few impacted strings. This also makes them loaded after enabling
filesystem redirection in `TEST_CLASS_SETUP` so that we resolve to the
correct path expected by x86.

Admittedly, I'm not the biggest fan of using that to fix the tests, but
it's better than the alternative which is a case-insensitive string
comparison. Also, the tests are testing fallback behavior, so this
doesn't really impact that. It just makes the tests more consistently
reliable.

This also removes the unused `pingCommandline` variable.

## Validation Steps Performed
 Tests pass
2026-04-15 19:13:41 +00:00
Windows Console Service Bot
33a80191c1 Localization Updates - URL dialog and PathTranslation - 04/11/2026 (#20096)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-04-15 14:09:19 -05:00
Dustin L. Howett
84ae7adec6 OS PR 14890400: fix defects caught with strict compiler switches (#20100)
Related work items: MSFT-53015560

Co-authored-by: Sudhakar Prabhu <sprabhu@microsoft.com>
2026-04-10 11:41:03 -07:00
Dustin L. Howett
a6ebdd3d4a render: check the thread exit condition after every long operation (#20097)
We have received an internal report that teardown on OneCore is still
hanging. It looks like there's a chance that `TriggerTeardown` is called
during `PaintFrame`, which may result in `_threadShouldKeepRunning`
getting set to `false` (TriggerTeardown) and `_redraw` being set to
`false` as well (PaintFrame). The thread will wait forever on `_redraw`
to be signalled, which it never will, because `TriggerTeardown` is
waiting for the thread to exit.

That is:

```
Render Thread      | ConIoSrv Thread
------------------------------------
Check _enabled     |
Wait on _redraw    |
Check _keepRunning | TriggerTeardown
Paint              |   _keepRunning = false
                   |   _redraw = true
    _redraw = false|   Signal _enabled
Paint Completes    |   Wait on thread
Check _enabled     |
Wait on _redraw    |
**DEADLOCK**       | **DEADLOCK**
                   v
```

This may not be an ideal fix, but at least it checks
`_threadShouldKeepRunning` after every "long" operation (waiting and
painting) now.
2026-04-09 16:34:09 -05:00
Dustin L. Howett
031998bfc3 Track the cursor dirty flag in the correct buffer (#20095)
Failure to do so will result in every console API requiring a cursor
update stalling for 500ms because we sent the update to the wrong
buffer.

Closes #20092
2026-04-08 22:08:28 +00:00
Dustin L. Howett
41e08a68bd Path translation setting: use 🡒 instead of -> (#20088)
It looks better, as decided by committee.
2026-04-07 16:38:51 -05:00
Dustin L. Howett
81170aff78 Display a warning dialog for unsafe URLs (#20065)
We are getting a sufficient number of LLM-generated security reports
telling us that Ctrl+click and a tooltip are insufficient protection
from users clicking on links to dangerous things.

This commit displays a warning that prevents users from blindly clicking
on dangerous things.

Dangerous things include:
- any non-http and non-https and non-file URLs
- any file URLs that point to something understandable as a "program"
(so, something which resides in `PATHEXT`.)

In doing this, I learned that `til::ends_with_insensitive_ascii` was
broken.

I also learned that ContentDialogs summoned by any event handler out of
TermControl::Pointer* would lose focus immediately. It turns out that in
the absolute earliest days of Terminal, when we first created the
UserControl that became TermControl, we added our Tapped event handler.

It unconditionally focused the control.

Since `Tapped` is a higher-level event handler than `PointerPressed`, it
was firing after the gesture that opened the content dialog and stealing
focus back.

I'm fairly certain we don't need it.

Refs #7562
2026-04-07 11:23:15 -05:00
Windows Console Service Bot
c90ace8326 Localization Updates - drag drop delimiter - 04/07/2026 03:05:15 (#20042)
Co-authored-by: Console Service Bot <consvc@microsoft.com>
2026-04-07 09:59:50 -05:00
Dustin L. Howett
fd30d00304 Draft-TerminalReleases: add nuget package support, remove asset hashes (#20061) 2026-04-06 17:34:28 -05:00
80 changed files with 999 additions and 516 deletions

View File

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

View File

@@ -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);

View File

@@ -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(); }

View File

@@ -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();

View File

@@ -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" };

View File

@@ -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)
{

View File

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

View File

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

View File

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

View File

@@ -669,9 +669,15 @@
<data name="UnsupportedSchemeText" xml:space="preserve">
<value>Ce type de lien nest 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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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);
}

View File

@@ -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());
}

View File

@@ -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;
}

View File

@@ -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);

View File

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

View File

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

View File

@@ -1935,8 +1935,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - args: event data
void TermControl::_TappedHandler(const IInspectable& /*sender*/, const TappedRoutedEventArgs& e)
{
Focus(FocusState::Pointer);
if (e.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Touch)
{
// Normally TSF would be responsible for showing the touch keyboard, but it's buggy for us:
@@ -2908,8 +2906,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else
{
// Do we ever get here (= uninitialized terminal)? If so: How?
assert(false);
return { 10, 10 };
}
}

View File

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

View File

@@ -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);

View File

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

View File

@@ -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 */)

View File

@@ -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();

View File

@@ -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);

View File

@@ -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");

View File

@@ -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;
};
};

View File

@@ -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; };

View File

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

View File

@@ -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();

View File

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

View File

@@ -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;
}
}

View File

@@ -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 };

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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;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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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">

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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 :\ -&gt; /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 :\ -&gt; /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:\ -&gt; /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:\ -&gt; 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 daccè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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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:\ -&gt; /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:\ -&gt; /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:\ -&gt; /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:\ -&gt; 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>

View File

@@ -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();
}

View File

@@ -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>();

View File

@@ -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; };

View File

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

View File

@@ -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();

View File

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

View File

@@ -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" />

View File

@@ -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" />

View 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.
}

View 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);
}

View 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);
}
}

View File

@@ -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());

View File

@@ -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;
}

View File

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

View File

@@ -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) };

View File

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

View File

@@ -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");
}

View File

@@ -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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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);

View File

@@ -166,7 +166,7 @@ void InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
// Unblock any callers inside SCREEN_INFORMATION::WaitForConptyCursorPositionToBeSynchronized().
// The cursor position has now been updated to the terminal's.
info.ResetConptyCursorPositionMayBeWrong();
info.GetActiveBuffer().ResetConptyCursorPositionMayBeWrong();
}
// Routine Description:

View File

@@ -31,6 +31,7 @@ Enum AssetType {
ApplicationBundle
PreinstallKit
GroupPolicy
NugetPackage
Zip
}
@@ -87,6 +88,9 @@ Class Asset {
} ElseIf (".zip" -eq $local:ext -and $local:filename -like 'GroupPolicy*') {
$this.Type = [AssetType]::GroupPolicy
$this.Architecture = "all"
} ElseIf (".nupkg" -eq $local:ext) {
$this.Type = [AssetType]::NugetPackage
$this.Architecture = "all"
} ElseIf (".zip" -eq $local:ext) {
$this.Type = [AssetType]::Zip
} ElseIf (".msixbundle" -eq $local:ext) {
@@ -108,6 +112,13 @@ Class Asset {
Write-Verbose "Parsing AppxManifest.xml"
$local:Manifest = [xml](Get-Content (Join-Path $local:directory AppxManifest.xml))
$this.ParseManifest($local:Manifest)
} ElseIf ($this.Type -Eq [AssetType]::NugetPackage) {
Write-Verbose "Cracking nuget package $($local:filename)"
& $script:tar -x -f $local:bundlePath -C $local:directory *.nuspec
$local:nuspec = Get-ChildItem $local:directory *.nuspec -Recurse | Select-Object -First 1
Write-Verbose "Parsing $($local:nuspec.Name)"
$local:Manifest = [xml](Get-Content $local:nuspec)
$this.ParseNuspec($local:Manifest)
} Else {
If ($this.Type -Ne [AssetType]::GroupPolicy) {
& $script:tar -x -f $this.Path -C $local:directory --strip-components=1 '*/wt.exe'
@@ -135,6 +146,12 @@ Class Asset {
$this.Version = $Manifest.Package.Identity.Version
}
[void]ParseNuspec([xml]$Nuspec) {
$this.Name = $Nuspec.package.metadata.id
$this.Version = ($Nuspec.package.metadata.version -split '-')[0]
$this.ExpandedVersion = $Nuspec.package.metadata.version
}
[void]ParseFilename([string]$filename) {
$parts = [IO.Path]::GetFileNameWithoutExtension($filename).Split("_")
$this.Name = $parts[0]
@@ -160,6 +177,9 @@ Class Asset {
GroupPolicy {
"{0}_{1}.zip" -f ($this.Name, $this.Version)
}
NugetPackage {
"{0}.{1}.nupkg" -f ($this.Name, $this.ExpandedVersion)
}
Default {
Throw "Unknown type $($_.Type)"
}
@@ -253,15 +273,11 @@ Function New-ReleaseBody([Release]$Release) {
If (-Not [String]::IsNullOrEmpty($zipAssetVersion)) {
$body += "_Binary files inside the unpackaged distribution archive bear the version number ``$zipAssetVersion``._`n`n"
}
$body += "### Asset Hashes`n`n";
ForEach($a in $Release.Assets) {
$body += "- {0}`n - SHA256 ``{1}```n" -f ($a.IdealFilename(), (Get-FileHash $a.Path -Algorithm SHA256 | Select-Object -Expand Hash))
}
Return $body
}
# Collect Assets from $Directory, figure out what those assets are
$Assets = Get-ChildItem $Directory -Recurse -Include *.msixbundle, *.zip | ForEach-Object {
$Assets = Get-ChildItem $Directory -Recurse -Include *.msixbundle, *.zip, *.nupkg -Exclude *.Wpf.*,*.symbols.nupkg | ForEach-Object {
[Asset]::CreateFromFile($_.FullName)
}