diff --git a/.github/actions/spelling/allow/allow.txt b/.github/actions/spelling/allow/allow.txt
index 27466018802..3ece2375e52 100644
--- a/.github/actions/spelling/allow/allow.txt
+++ b/.github/actions/spelling/allow/allow.txt
@@ -17,6 +17,7 @@ CMMI
copyable
Counterintuitively
CtrlDToClose
+CVS
CUI
cybersecurity
dalet
diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt
index 5ae7e5753df..839fcbe76b2 100644
--- a/.github/actions/spelling/allow/apis.txt
+++ b/.github/actions/spelling/allow/apis.txt
@@ -1,3 +1,5 @@
+aalt
+abvm
ACCEPTFILES
ACCESSDENIED
acl
@@ -36,6 +38,7 @@ delayimp
DERR
dlldata
DNE
+dnom
DONTADDTORECENT
DWMSBT
DWMWA
@@ -49,6 +52,7 @@ EXPCMDFLAGS
EXPCMDSTATE
filetime
FILTERSPEC
+fina
FORCEFILESYSTEM
FORCEMINIMIZE
frac
@@ -120,6 +124,7 @@ LSHIFT
LTGRAY
MAINWINDOW
MAXIMIZEBOX
+medi
memchr
memicmp
MENUCOMMAND
@@ -150,6 +155,7 @@ NOTIFYBYPOS
NOTIFYICON
NOTIFYICONDATA
ntprivapi
+numr
oaidl
ocidl
ODR
@@ -175,9 +181,11 @@ REGCLS
RETURNCMD
rfind
RLO
+rnrn
ROOTOWNER
roundf
RSHIFT
+rvrn
SACL
schandle
SEH
diff --git a/.github/actions/spelling/allow/microsoft.txt b/.github/actions/spelling/allow/microsoft.txt
index d14b0a75e3a..5e7aa5c06ee 100644
--- a/.github/actions/spelling/allow/microsoft.txt
+++ b/.github/actions/spelling/allow/microsoft.txt
@@ -46,6 +46,7 @@ MSAA
msixbundle
MSVC
MSVCP
+mtu
muxc
netcore
Onefuzz
diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt
index 02d18ffcb97..9c3928d83cb 100644
--- a/.github/actions/spelling/expect/expect.txt
+++ b/.github/actions/spelling/expect/expect.txt
@@ -453,6 +453,7 @@ DECSTBM
DECSTGLT
DECSTR
DECSWL
+DECSWT
DECTABSR
DECTCEM
DECXCPR
diff --git a/OpenConsole.sln b/OpenConsole.sln
index e699c77cece..809dd25a346 100644
--- a/OpenConsole.sln
+++ b/OpenConsole.sln
@@ -270,7 +270,6 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHostApp", "src\cascadia\LocalTests_TerminalApp\TestHostApp\TestHostApp.vcxproj", "{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
- {CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {CA5CAD1A-9B68-456A-B13E-C8218070DC42}
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}
EndProjectSection
EndProject
@@ -350,7 +349,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_SettingsModel", "src\cascadia\LocalTests_SettingsModel\SettingsModel.LocalTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_SettingsModel", "src\cascadia\UnitTests_SettingsModel\SettingsModel.UnitTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
@@ -413,6 +412,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TerminalStress", "src\tools
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingTests", "src\tools\RenderingTests\RenderingTests.vcxproj", "{37C995E0-2349-4154-8E77-4A52C0C7F46D}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UIHelpers", "src\cascadia\UIHelpers\UIHelpers.vcxproj", "{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchcat", "src\tools\benchcat\benchcat.vcxproj", "{2C836962-9543-4CE5-B834-D28E1F124B66}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleMonitor", "src\tools\ConsoleMonitor\ConsoleMonitor.vcxproj", "{328729E9-6723-416E-9C98-951F1473BBE1}"
@@ -2357,6 +2358,29 @@ Global
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|ARM64.ActiveCfg = Release|ARM64
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x64.ActiveCfg = Release|x64
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x86.ActiveCfg = Release|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|Any CPU.ActiveCfg = AuditMode|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x64.ActiveCfg = AuditMode|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x64.Build.0 = AuditMode|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x86.ActiveCfg = AuditMode|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|ARM64.Build.0 = Debug|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x64.ActiveCfg = Debug|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x64.Build.0 = Debug|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x86.ActiveCfg = Debug|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x86.Build.0 = Debug|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|Any CPU.ActiveCfg = Release|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|ARM64.ActiveCfg = Release|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|ARM64.Build.0 = Release|ARM64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x64.ActiveCfg = Release|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x64.Build.0 = Release|x64
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.ActiveCfg = Release|Win32
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.Build.0 = Release|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|x64.ActiveCfg = Release|x64
@@ -2512,6 +2536,7 @@ Global
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {40BD8415-DD93-4200-8D82-498DDDC08CC8}
{613CCB57-5FA9-48EF-80D0-6B1E319E20C4} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{37C995E0-2349-4154-8E77-4A52C0C7F46D} = {A10C4720-DCA4-4640-9749-67F4314F527C}
+ {6515F03F-E56D-4DB4-B23D-AC4FB80DB36F} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
{2C836962-9543-4CE5-B834-D28E1F124B66} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{328729E9-6723-416E-9C98-951F1473BBE1} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{BE92101C-04F8-48DA-99F0-E1F4F1D2DC48} = {A10C4720-DCA4-4640-9749-67F4314F527C}
diff --git a/build/pipelines/templates-v2/job-run-pgo-tests.yml b/build/pipelines/templates-v2/job-run-pgo-tests.yml
index 817d97ff9ce..f4208bf9553 100644
--- a/build/pipelines/templates-v2/job-run-pgo-tests.yml
+++ b/build/pipelines/templates-v2/job-run-pgo-tests.yml
@@ -56,6 +56,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run PGO Tests'
inputs:
+ pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: >-
diff --git a/build/pipelines/templates-v2/job-test-project.yml b/build/pipelines/templates-v2/job-test-project.yml
index 1cd8e2bef67..5c53d76cfd0 100644
--- a/build/pipelines/templates-v2/job-test-project.yml
+++ b/build/pipelines/templates-v2/job-test-project.yml
@@ -44,6 +44,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Unit Tests'
inputs:
+ pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
@@ -52,6 +53,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Feature Tests'
inputs:
+ pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
diff --git a/build/rules/GenerateFeatureFlags.proj b/build/rules/GenerateFeatureFlags.proj
index 686365c0ca2..eb6b9783bce 100644
--- a/build/rules/GenerateFeatureFlags.proj
+++ b/build/rules/GenerateFeatureFlags.proj
@@ -30,6 +30,7 @@
$(SolutionDir)obj\$(Configuration)\GenerateFeatureFlags\
$(SolutionDir)bin\$(Configuration)\
+ <_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Canary'">Canary
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Preview'">Preview
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Release'">Release
<_WTBrandingName Condition="'$(_WTBrandingName)'==''">Dev
diff --git a/build/scripts/Run-Tests.ps1 b/build/scripts/Run-Tests.ps1
index bd4cf28fc50..c9a37001c72 100644
--- a/build/scripts/Run-Tests.ps1
+++ b/build/scripts/Run-Tests.ps1
@@ -16,22 +16,48 @@ Param(
# Find test DLLs based on the provided root, match pattern, and recursion
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
-$args = @()
+$teArgs = @()
# Check if the LogPath parameter is provided and enable WTT logging
if ($LogPath) {
- $args += '/enablewttlogging'
- $args += '/appendwttlogging'
- $args += "/logFile:$LogPath"
+ $teArgs += '/enablewttlogging'
+ $teArgs += '/appendwttlogging'
+ $teArgs += "/logFile:$LogPath"
Write-Host "WTT Logging Enabled"
}
-# Invoke the te.exe executable with arguments and test DLLs
-& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
+$rootTe = "$Root\te.exe"
-# Check the exit code of the te.exe process and exit accordingly
-if ($LASTEXITCODE -ne 0) {
- Exit $LASTEXITCODE
+# Some of our test fixtures depend on resources.pri in the same folder as the .exe hosting them.
+# Unfortunately, that means that we need to run the te.exe *next to* each test DLL we discover.
+# This code establishes a mapping from te.exe to test DLL (or DLLs)
+$testDllTaefGroups = $testDlls | % {
+ $localTe = Get-Item (Join-Path (Split-Path $_ -Parent) "te.exe") -EA:Ignore
+ If ($null -eq $localTe) {
+ $finalTePath = $rootTe
+ } Else {
+ $finalTePath = $localTe.FullName
+ }
+ [PSCustomObject]@{
+ TePath = $finalTePath;
+ TestDll = $_;
+ }
+}
+
+# Invoke the te.exe executables with arguments and test DLLs
+$anyFailed = $false
+$testDllTaefGroups | Group-Object TePath | % {
+ $te = $_.Group[0].TePath
+ $dlls = $_.Group.TestDll
+ Write-Verbose "Running $te (for $($dlls.Name))"
+ & $te $teArgs $dlls.FullName $AdditionalTaefArguments
+ if ($LASTEXITCODE -ne 0) {
+ $anyFailed = $true
+ }
+}
+
+if ($anyFailed) {
+ Exit 1
}
Exit 0
diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.cpp b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp
index fbea8e334f1..b9373d7e6d2 100644
--- a/scratch/ScratchIslandApp/SampleApp/MyPage.cpp
+++ b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp
@@ -31,9 +31,12 @@ namespace winrt::SampleApp::implementation
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...",
winrt::hstring{},
L"",
+ false,
+ L"",
nullptr,
32,
80,
+ winrt::guid(),
winrt::guid()) };
// "Microsoft.Terminal.TerminalConnection.ConptyConnection"
diff --git a/src/buffer/out/Row.cpp b/src/buffer/out/Row.cpp
index 7729cdcdbd4..4722dc0dfc4 100644
--- a/src/buffer/out/Row.cpp
+++ b/src/buffer/out/Row.cpp
@@ -92,47 +92,35 @@ CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* cha
// If given a position (`offset`) inside the ROW's text, this function will return the corresponding column.
// This function in particular returns the glyph's first column.
-til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t offset) noexcept
+til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept
{
- offset = clamp(offset, 0, _lastCharOffset);
+ targetOffset = clamp(targetOffset, 0, _lastCharOffset);
+
+ // This code needs to fulfill two conditions on top of the obvious (a forward/backward search):
+ // A: We never want to stop on a column that is marked with CharOffsetsTrailer (= "GetLeadingColumn").
+ // B: With these parameters we always want to stop at currentOffset=4:
+ // _charOffsets={4, 6}
+ // currentOffset=4 *OR* 6
+ // targetOffset=5
+ // This is because we're being asked for a "LeadingColumn", while the caller gave us the offset of a
+ // trailing surrogate pair or similar. Returning the column of the leading half is the correct choice.
auto col = _currentColumn;
- const auto currentOffset = _charOffsets[col] & CharOffsetsMask;
+ auto currentOffset = _charOffsets[col];
- // Goal: Move the _currentColumn cursor to a cell which contains the given target offset.
- // Depending on where the target offset is we have to either search forward or backward.
- if (offset < currentOffset)
+ // A plain forward-search until we find our targetOffset.
+ // This loop may iterate too far and thus violate our example in condition B, however...
+ while (targetOffset > (currentOffset & CharOffsetsMask))
{
- // Backward search.
- // Goal: Find the first preceding column where the offset is <= the target offset. This results in the first
- // cell that contains our target offset, even if that offset is in the middle of a long grapheme.
- //
- // We abuse the fact that the trailing half of wide glyphs is marked with CharOffsetsTrailer to our advantage.
- // Since they're >0x8000, the `offset < _charOffsets[col]` check will always be true and ensure we iterate over them.
- //
- // Since _charOffsets cannot contain negative values and because offset has been
- // clamped to be positive we naturally exit when reaching the first column.
- for (; offset < _charOffsets[col - 1]; --col)
- {
- }
+ currentOffset = _charOffsets[++col];
}
- else if (offset > currentOffset)
+ // This backward-search is not just a counter-part to the above, but simultaneously also handles conditions A and B.
+ // It abuses the fact that columns marked with CharOffsetsTrailer are >0x8000 and targetOffset is always <0x8000.
+ // This means we skip all "trailer" columns when iterating backwards, and only stop on a non-trailer (= condition A).
+ // Condition B is fixed simply because we iterate backwards after the forward-search (in that exact order).
+ while (targetOffset < currentOffset)
{
- // Forward search.
- // Goal: Find the first subsequent column where the offset is > the target offset.
- // We stop 1 column before that however so that the next loop works correctly.
- // It's the inverse of the loop above.
- //
- // Since offset has been clamped to be at most 1 less than the maximum
- // _charOffsets value the loop naturally exits before hitting the end.
- for (; offset >= (_charOffsets[col + 1] & CharOffsetsMask); ++col)
- {
- }
- // Now that we found the cell that definitely includes this char offset,
- // we have to iterate back to the cell's starting column.
- for (; WI_IsFlagSet(_charOffsets[col], CharOffsetsTrailer); --col)
- {
- }
+ currentOffset = _charOffsets[--col];
}
_currentColumn = col;
diff --git a/src/buffer/out/Row.hpp b/src/buffer/out/Row.hpp
index af8088c3ccd..197343df6d8 100644
--- a/src/buffer/out/Row.hpp
+++ b/src/buffer/out/Row.hpp
@@ -71,7 +71,7 @@ struct CharToColumnMapper
{
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept;
- til::CoordType GetLeadingColumnAt(ptrdiff_t offset) noexcept;
+ til::CoordType GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept;
til::CoordType GetTrailingColumnAt(ptrdiff_t offset) noexcept;
til::CoordType GetLeadingColumnAt(const wchar_t* str) noexcept;
til::CoordType GetTrailingColumnAt(const wchar_t* str) noexcept;
diff --git a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj
index ad3b48c7cb5..c52d012baec 100644
--- a/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj
+++ b/src/buffer/out/ut_textbuffer/TextBuffer.Unit.Tests.vcxproj
@@ -14,6 +14,7 @@
+
Create
@@ -41,4 +42,4 @@
-
\ No newline at end of file
+
diff --git a/src/buffer/out/ut_textbuffer/UTextAdapterTests.cpp b/src/buffer/out/ut_textbuffer/UTextAdapterTests.cpp
new file mode 100644
index 00000000000..ee879f4f677
--- /dev/null
+++ b/src/buffer/out/ut_textbuffer/UTextAdapterTests.cpp
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "precomp.h"
+
+#include "WexTestClass.h"
+#include "../textBuffer.hpp"
+#include "../../renderer/inc/DummyRenderer.hpp"
+
+template<>
+class WEX::TestExecution::VerifyOutputTraits>
+{
+public:
+ static WEX::Common::NoThrowString ToString(const std::vector& vec)
+ {
+ WEX::Common::NoThrowString str;
+ str.Append(L"{ ");
+ for (size_t i = 0; i < vec.size(); ++i)
+ {
+ const auto& s = vec[i];
+ if (i != 0)
+ {
+ str.Append(L", ");
+ }
+ str.AppendFormat(L"{(%d, %d), (%d, %d)}", s.start.x, s.start.y, s.end.x, s.end.y);
+ }
+ str.Append(L" }");
+ return str;
+ }
+};
+
+class UTextAdapterTests
+{
+ TEST_CLASS(UTextAdapterTests);
+
+ TEST_METHOD(Unicode)
+ {
+ DummyRenderer renderer;
+ TextBuffer buffer{ til::size{ 24, 1 }, TextAttribute{}, 0, false, renderer };
+
+ RowWriteState state{
+ .text = L"abc πΆπ·πΈ abc γγ³γ‘γγ",
+ };
+ buffer.Write(0, TextAttribute{}, state);
+ VERIFY_IS_TRUE(state.text.empty());
+
+ static constexpr auto s = [](til::CoordType beg, til::CoordType end) -> til::point_span {
+ return { { beg, 0 }, { end, 0 } };
+ };
+
+ auto expected = std::vector{ s(0, 2), s(8, 10) };
+ auto actual = buffer.SearchText(L"abc", false);
+ VERIFY_ARE_EQUAL(expected, actual);
+
+ expected = std::vector{ s(5, 5) };
+ actual = buffer.SearchText(L"π·", false);
+ VERIFY_ARE_EQUAL(expected, actual);
+
+ expected = std::vector{ s(12, 15) };
+ actual = buffer.SearchText(L"γγ³", false);
+ VERIFY_ARE_EQUAL(expected, actual);
+ }
+};
diff --git a/src/buffer/out/ut_textbuffer/sources b/src/buffer/out/ut_textbuffer/sources
index 570467fce63..842246aaee6 100644
--- a/src/buffer/out/ut_textbuffer/sources
+++ b/src/buffer/out/ut_textbuffer/sources
@@ -17,6 +17,7 @@ SOURCES = \
ReflowTests.cpp \
TextColorTests.cpp \
TextAttributeTests.cpp \
+ UTextAdapterTests.cpp \
DefaultResource.rc \
TARGETLIBS = \
diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
index a940cc915f3..8116e9e4574 100644
--- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
+++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
@@ -4,7 +4,7 @@
#include "pch.h"
#include "../TerminalApp/TerminalPage.h"
-#include "../LocalTests_SettingsModel/TestUtils.h"
+#include "../UnitTests_SettingsModel/TestUtils.h"
using namespace Microsoft::Console;
using namespace WEX::Logging;
diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj
index 9e2029c9bcc..8d431bffcc0 100644
--- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj
+++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj
@@ -133,7 +133,6 @@
-
diff --git a/src/cascadia/TerminalApp/CommandPalette.idl b/src/cascadia/TerminalApp/CommandPalette.idl
index 4bb72f46dda..e73d935a883 100644
--- a/src/cascadia/TerminalApp/CommandPalette.idl
+++ b/src/cascadia/TerminalApp/CommandPalette.idl
@@ -2,13 +2,12 @@
// Licensed under the MIT license.
import "TabBase.idl";
-import "IDirectKeyListener.idl";
import "HighlightedTextControl.idl";
import "FilteredCommand.idl";
namespace TerminalApp
{
- [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
+ [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
CommandPalette();
diff --git a/src/cascadia/TerminalApp/CommandPalette.xaml b/src/cascadia/TerminalApp/CommandPalette.xaml
index c8100e3568c..2e143a5f12c 100644
--- a/src/cascadia/TerminalApp/CommandPalette.xaml
+++ b/src/cascadia/TerminalApp/CommandPalette.xaml
@@ -9,7 +9,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:model="using:Microsoft.Terminal.Settings.Model"
+ xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,12 +23,6 @@
-
-
-
-
-
-
+ Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
+ Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
+ Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(PrefixCharacter), Mode=OneWay}" />
+ Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
+
+
@@ -61,7 +66,7 @@
@@ -168,7 +173,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="Cascadia Code"
- Foreground="{x:Bind local:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
+ Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Text="{x:Bind Name, Mode=OneWay}"
TextTrimming="WordEllipsis" />
@@ -197,7 +202,7 @@
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
SelectionChanged="FontFace_SelectionChanged"
Style="{StaticResource ComboBoxSettingStyle}"
- Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(ShowAllFonts), Mode=OneWay}" />
+ Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ShowAllFonts), Mode=OneWay}" />
+ Value="{x:Bind mtu:Converters.FontWeightToDouble(Appearance.FontWeight), BindBack=Appearance.SetFontWeightFromDouble, Mode=TwoWay}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Text="{x:Bind mtu:Converters.StringOrEmptyIfPlaceholder('desktopWallpaper', Appearance.BackgroundImagePath), Mode=TwoWay, BindBack=Appearance.SetBackgroundImagePath}" />
+ Value="{x:Bind mtu:Converters.PercentageToPercentageValue(Appearance.BackgroundImageOpacity), BindBack=Appearance.SetBackgroundImageOpacityFromPercentageValue, Mode=TwoWay}" />
+ Text="{x:Bind mtu:Converters.AppendPercentageSign(BIOpacitySlider.Value), Mode=OneWay}" />
diff --git a/src/cascadia/TerminalSettingsEditor/ColorSchemes.xaml b/src/cascadia/TerminalSettingsEditor/ColorSchemes.xaml
index 7d2fad0d4d7..c708a729d05 100644
--- a/src/cascadia/TerminalSettingsEditor/ColorSchemes.xaml
+++ b/src/cascadia/TerminalSettingsEditor/ColorSchemes.xaml
@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
+ xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -22,7 +23,7 @@
x:DataType="local:ColorTableEntry">
@@ -89,7 +90,7 @@
Height="48"
Padding="12,11,8,8"
VerticalAlignment="Center"
- Background="{x:Bind local:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
+ Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
ColumnSpacing="2"
CornerRadius="4"
RowSpacing="2">
@@ -195,7 +196,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="Cascadia Code"
- Foreground="{x:Bind local:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
+ Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Text="{x:Bind Name, Mode=OneWay}" />
- {
- static winrt::hstring AppendPercentageSign(double value);
- static winrt::Windows::UI::Text::FontWeight DoubleToFontWeight(double value);
- static winrt::Windows::UI::Xaml::Media::SolidColorBrush ColorToBrush(winrt::Windows::UI::Color color);
- static double FontWeightToDouble(winrt::Windows::UI::Text::FontWeight fontWeight);
- static bool InvertBoolean(bool value);
- static winrt::Windows::UI::Xaml::Visibility InvertedBooleanToVisibility(bool value);
- static double MaxValueFromPaddingString(winrt::hstring paddingString);
- static int PercentageToPercentageValue(double value);
- static double PercentageValueToPercentage(double value);
- static bool StringsAreNotEqual(winrt::hstring expected, winrt::hstring actual);
- static winrt::Windows::UI::Xaml::Visibility StringNotEmptyToVisibility(winrt::hstring value);
- static winrt::hstring StringOrEmptyIfPlaceholder(winrt::hstring placeholder, winrt::hstring value);
- };
-}
-
-namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
-{
- BASIC_FACTORY(Converters);
-}
diff --git a/src/cascadia/TerminalSettingsEditor/EditColorScheme.xaml b/src/cascadia/TerminalSettingsEditor/EditColorScheme.xaml
index e629c5ce3b6..1279123c4ef 100644
--- a/src/cascadia/TerminalSettingsEditor/EditColorScheme.xaml
+++ b/src/cascadia/TerminalSettingsEditor/EditColorScheme.xaml
@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
+ xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -56,7 +57,7 @@
@@ -74,7 +75,7 @@
@@ -90,7 +91,7 @@
MaxWidth="{StaticResource StandardControlMaxWidth}"
Margin="4"
HorizontalAlignment="Left"
- Background="{x:Bind local:Converters.ColorToBrush(ViewModel.BackgroundColor.Color), Mode=OneWay}"
+ Background="{x:Bind mtu:Converters.ColorToBrush(ViewModel.BackgroundColor.Color), Mode=OneWay}"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1">
@@ -198,7 +199,7 @@
+ Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.IsEditable), Mode=OneWay}">
@@ -71,7 +72,7 @@
-
diff --git a/src/cascadia/TerminalSettingsEditor/Launch.xaml b/src/cascadia/TerminalSettingsEditor/Launch.xaml
index 5a30fa771d8..e68076a5032 100644
--- a/src/cascadia/TerminalSettingsEditor/Launch.xaml
+++ b/src/cascadia/TerminalSettingsEditor/Launch.xaml
@@ -9,6 +9,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -22,7 +23,6 @@
x:DataType="local:EnumEntry">
-