mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-07 14:50:55 +00:00
Compare commits
8 Commits
dev/miniks
...
release-0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d624070755 | ||
|
|
0f3d25cea3 | ||
|
|
443e06d836 | ||
|
|
8e05772329 | ||
|
|
f87454fa74 | ||
|
|
ba3247952a | ||
|
|
c636c2b121 | ||
|
|
c833c93c1d |
15
.github/ISSUE_TEMPLATE/Bug_Report.md
vendored
15
.github/ISSUE_TEMPLATE/Bug_Report.md
vendored
@@ -1,25 +1,12 @@
|
||||
---
|
||||
name: Bug report 🐛
|
||||
about: Report errors or unexpected behavior
|
||||
title: "Bug Report (IF I DO NOT CHANGE THIS THE ISSUE WILL BE AUTO-CLOSED)"
|
||||
title: "Bug Report"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
||||
|
||||
I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING:
|
||||
1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement.
|
||||
2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement.
|
||||
3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number).
|
||||
4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement.
|
||||
5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement.
|
||||
|
||||
All good? Then proceed!
|
||||
-->
|
||||
|
||||
<!--
|
||||
This bug tracker is monitored by Windows Terminal development team and other technical folks.
|
||||
|
||||
|
||||
13
.github/ISSUE_TEMPLATE/Feature_Request.md
vendored
13
.github/ISSUE_TEMPLATE/Feature_Request.md
vendored
@@ -7,19 +7,6 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
||||
|
||||
I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING:
|
||||
1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement.
|
||||
2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement.
|
||||
3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number).
|
||||
4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement.
|
||||
5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement.
|
||||
|
||||
All good? Then proceed!
|
||||
-->
|
||||
|
||||
# Summary of the new feature/enhancement
|
||||
|
||||
<!--
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
<!-- Add repositories here to the list of available repositories -->
|
||||
|
||||
<!-- Dependencies that we must carry because they're not on public nuget feeds right now. -->
|
||||
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
|
||||
|
||||
<!-- Use our own NuGet Feed -->
|
||||
<add key="Windows Terminal NuGet Feed" value="https://terminalnuget.blob.core.windows.net/feed/index.json" />
|
||||
<add key="Static Package Dependencies" value="dep\packages" />
|
||||
|
||||
<!-- Internal NuGet feeds that may not be accessible outside Microsoft corporate network -->
|
||||
<!--<add key="TAEF - internal" value="https://microsoft.pkgs.visualstudio.com/DefaultCollection/_packaging/Taef/nuget/v3/index.json" />
|
||||
|
||||
139
OpenConsole.sln
139
OpenConsole.sln
@@ -1,12 +1,8 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29001.49
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2008
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Terminal", "Terminal", "{59840756-302F-44DF-AA47-441A9D673202}"
|
||||
EndProject
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CascadiaPackage", "src\cascadia\CascadiaPackage\CascadiaPackage.wapproj", "{CA5CAD1A-224A-4171-B13A-F16E576FDD12}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Host.EXE", "src\host\exe\Host.EXE.vcxproj", "{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0CF235BD-2DA0-407E-90EE-C467E8BBC714} = {0CF235BD-2DA0-407E-90EE-C467E8BBC714}
|
||||
@@ -167,6 +163,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BufferOut", "src\buffer\out
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDx", "src\renderer\dx\lib\dx.vcxproj", "{48D21369-3D7B-4431-9967-24E81292CF62}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Terminal", "Terminal", "{59840756-302F-44DF-AA47-441A9D673202}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalConnection", "src\cascadia\TerminalConnection\TerminalConnection.vcxproj", "{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalCore", "src\cascadia\TerminalCore\lib\TerminalCore-lib.vcxproj", "{CA5CAD1A-ABCD-429C-B551-8562EC954746}"
|
||||
@@ -182,6 +180,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalControl", "src\casc
|
||||
{1CF55140-EF6A-4736-A403-957E4F7430BB} = {1CF55140-EF6A-4736-A403-957E4F7430BB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CascadiaPackage", "src\cascadia\CascadiaPackage\CascadiaPackage.wapproj", "{CA5CAD1A-224A-4171-B13A-F16E576FDD12}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
@@ -193,7 +193,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\casc
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
|
||||
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
@@ -203,6 +202,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalSettings", "src\cas
|
||||
EndProject
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "OpenConsolePackage", "pkg\appx\OpenConsolePackage.wapproj", "{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.UI.Xaml.Markup", "src\cascadia\Microsoft.UI.Xaml.Markup\Microsoft.UI.Xaml.Markup.vcxproj", "{015A0047-772D-4F1A-88C9-45C18F0ADFB6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalCore", "src\cascadia\UnitTests_TerminalCore\UnitTests.vcxproj", "{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Internal", "src\internal\internal.vcxproj", "{EF3E32A7-5FF6-42B4-B6E2-96CD7D033F00}"
|
||||
@@ -232,17 +233,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{89CDCC
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types.Unit.Tests", "src\types\ut_types\Types.Unit.Tests.vcxproj", "{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "src\cascadia\ut_app\TerminalApp.UnitTests.vcxproj", "{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|ARM64 = AuditMode|ARM64
|
||||
@@ -256,33 +246,6 @@ Global
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.Deploy.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.ActiveCfg = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.Build.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.Deploy.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.Build.0 = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.ActiveCfg = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.Build.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.Deploy.0 = Release|x86
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
@@ -979,6 +942,33 @@ Global
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|ARM64.Deploy.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.ActiveCfg = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.Build.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.AuditMode|x86.Deploy.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.Build.0 = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x64.Deploy.0 = Release|x64
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.ActiveCfg = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.Build.0 = Release|x86
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12}.Release|x86.Deploy.0 = Release|x86
|
||||
{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
@@ -1060,6 +1050,24 @@ Global
|
||||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}.Release|x86.ActiveCfg = Release|x86
|
||||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}.Release|x86.Build.0 = Release|x86
|
||||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}.Release|x86.Deploy.0 = Release|x86
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|x64.Build.0 = Release|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|x64.Build.0 = Debug|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|x64.ActiveCfg = Release|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|x64.Build.0 = Release|x64
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6}.Release|x86.Build.0 = Release|Win32
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
@@ -1114,48 +1122,11 @@ Global
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x64.Build.0 = Release|x64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.ActiveCfg = Release|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x86.Build.0 = Release|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x64.Build.0 = Release|x64
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{345FD5A4-B32B-4F29-BD1C-B033BD2C35CC} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{4C8E6BB0-4713-4ADB-BD04-81628ECEAF20} = {81C352DB-1818-45B7-A284-18E259F1CC87}
|
||||
@@ -1197,10 +1168,12 @@ Global
|
||||
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-224A-4171-B13A-F16E576FDD12} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{015A0047-772D-4F1A-88C9-45C18F0ADFB6} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{2C2BEEF4-9333-4D05-B12A-1905CBF112F9} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{EF3E32A7-5FF6-42B4-B6E2-96CD7D033F00} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{16376381-CE22-42BE-B667-C6B35007008D} = {81C352DB-1818-45B7-A284-18E259F1CC87}
|
||||
@@ -1208,8 +1181,6 @@ Global
|
||||
{05500DEF-2294-41E3-AF9A-24E580B82836} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{1E4A062E-293B-4817-B20D-BF16B979E350} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||
|
||||
26
README.md
26
README.md
@@ -8,7 +8,7 @@
|
||||
* [Sample projects](https://github.com/Microsoft/Terminal/tree/master/samples) that show how to consume the Windows Console APIs
|
||||
|
||||
#### Other related repositories include:
|
||||
* [Console API Documentation](https://github.com/MicrosoftDocs/Console-Docs)
|
||||
* [Console API Documentation](https://github.com/MicrosoftDocs/Console-Docs/issues)
|
||||
|
||||
### Build Status
|
||||
|
||||
@@ -55,14 +55,16 @@ Further, we realized that this would allow us to build the terminal's renderer a
|
||||
|
||||
## Where can I download Windows Terminal?
|
||||
|
||||
### The Windows Terminal preview can be downloaded from the Microsoft Store.
|
||||
### There are no binaries to download quite yet.
|
||||
|
||||
[https://www.microsoft.com/en-us/p/windows-terminal-preview/9n0dx20hk701](https://www.microsoft.com/en-us/p/windows-terminal-preview/9n0dx20hk701)
|
||||
The Windows Terminal is in the _very early_ alpha stage, and not ready for the general public quite yet. If you want to jump in early, you can try building it yourself from source.
|
||||
|
||||
Otherwise, you'll need to wait until Mid-June for an official preview build to drop.
|
||||
|
||||
## I built and ran the new Terminal, but I just get a blank window app!
|
||||
|
||||
Make sure you are building for your computer's architecture. If your box has a 64-bit Windows, change your Solution Platform to x64.
|
||||
To check your OS architecture go to Settings -> System -> About (or Win+X -> System) and under `Device specifications` check for the `System type`.
|
||||
Make sure you are building for your computer's architecture. If your box has a 64-bit Windows change your Solution Platform to x64.
|
||||
To check your OS architecture go to Settings -> System -> About (or Win+X -> System) and under `Device specifications` check for the `System type`
|
||||
|
||||
## I built and ran the new Terminal, but it looks just like the old console! What gives?
|
||||
|
||||
@@ -79,7 +81,7 @@ Secondly, try pressing <kbd>Ctrl</kbd> + <kbd>T</kbd>. The tabs are hidden when
|
||||
|
||||
## Debugging
|
||||
|
||||
* To debug in VS, right click on CascadiaPackage (from VS Solution Explorer) and go to properties, in the Debug menu, change "Application process" and "Background task process" to "Native Only".
|
||||
* To debug in VS, right click on CascadiaPackage (from VS Solution Explorer) and go to properties, in the Debug menu, change "Application process" and "Background task process" to "Native Only"
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -115,14 +117,14 @@ If you would like to ask a question that you feel doesn't warrant an issue (yet)
|
||||
|
||||
## Build Prerequisites
|
||||
|
||||
* You must be running Windows 1903 (build >= 10.0.18362.0) or above in order to run Windows Terminal.
|
||||
* You must have the [1903 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) (build 10.0.18362.0) installed.
|
||||
* You must have at least [VS 2019](https://visualstudio.microsoft.com/downloads/) installed.
|
||||
* You must install the following Workloads via the VS Installer. Opening the solution will [prompt you to install missing components automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/).
|
||||
* You must be running Windows 1903 (build >= 10.0.18362.0) or above in order to run Windows Terminal
|
||||
* You must have the [1903 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) (build 10.0.18362.0) installed
|
||||
* You must have at least [VS 2017](https://visualstudio.microsoft.com/downloads/) installed.
|
||||
* You must install the following Workloads via the VS Installer. If you're running VS 2019, opening the solution will [prompt you to install missing components automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/).
|
||||
- Desktop Development with C++
|
||||
- Universal Windows Platform Development
|
||||
- **The following Individual Components**
|
||||
- C++ (v142) Universal Windows Platform Tools
|
||||
- Also install the following Individual Component:
|
||||
- C++ (v141) Universal Windows Platform Tools
|
||||
|
||||
* You must also [enable Developer Mode in the Windows Settings app](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) to locally install and run the Terminal app.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
variables:
|
||||
BuildConfiguration: AuditMode
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool: { vmImage: windows-2019 }
|
||||
pool: { vmImage: vs2017-win2016 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
vsVersion: 16.0
|
||||
vsVersion: 15.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool: { vmImage: windows-2019 }
|
||||
pool: { vmImage: vs2017-win2016 }
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
|
||||
@@ -39,7 +39,7 @@ steps:
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
vsVersion: 16.0
|
||||
vsVersion: 15.0
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
jobs:
|
||||
- job: CodeFormatCheck
|
||||
displayName: Proper Code Formatting Check
|
||||
pool: { vmImage: windows-2019 }
|
||||
pool: { vmImage: vs2017-win2016 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
|
||||
7
dep/packages/README.md
Normal file
7
dep/packages/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
These packages are redistributed inside this folder because they are not yet available on a public NuGet feed.
|
||||
|
||||
## Microsoft.UI.XAML
|
||||
This package is a custom development build fork to help us light up tab support. It will eventually go onto the same public feed as the existing `Microsoft.UI.XAML` package that's currently available on NuGet.org
|
||||
|
||||
## TAEF.Redist.WLK
|
||||
This package is vetted for public redistribution and release, but the TAEF team hasn't set up a public feed to consume it yet. If/when they do, we'll move to that.
|
||||
BIN
dep/packages/microsoft.ui.xaml.2.1.190405001-prerelease.nupkg
Normal file
BIN
dep/packages/microsoft.ui.xaml.2.1.190405001-prerelease.nupkg
Normal file
Binary file not shown.
BIN
dep/packages/taef.redist.wlk.10.30.180808002.nupkg
Normal file
BIN
dep/packages/taef.redist.wlk.10.30.180808002.nupkg
Normal file
Binary file not shown.
13
doc/bot.md
13
doc/bot.md
@@ -56,13 +56,6 @@ We'll be using tags, primarily, to help us understand what needs attention, what
|
||||
#### Enforce tag system
|
||||
- When an issue is opened or labels are changed in any way, we will check if the tagging matches the system. If not, it will get `Needs-Tag-Fix`. The system is to have an `Area-`, `Issue-`, and `Product-` tag for all open things, and also a `Resolution-` for closed ones.
|
||||
- When the tags from appropriate categories are applied, it will auto-remove the `Needs-Tag-Fix` tag.
|
||||
- `Resolution-Duplicate` is sufficient to fix all tagging. (`Area-`, `Issue-`, and `Product-` are not needed for a duplicate.)
|
||||
|
||||
#### Clean-up low quality issues
|
||||
- If an issue is filed with an incomplete title...
|
||||
- If an issue is filed with nothing in the body...
|
||||
- If an issue is filed matching a pattern that happens all the time (common duplicate phrase, obvious multiple-issues-in-one pattern)...
|
||||
- Then close the issue automatically informing the opener that they can resolve the problem and reopen the issue. (See Bug/Feature templates for example situations.)
|
||||
|
||||
### PR Management
|
||||
|
||||
@@ -92,11 +85,5 @@ We'll be using tags, primarily, to help us understand what needs attention, what
|
||||
- Will automatically remove the `AutoMerge` label if changes are pushed by someone *without* Write Access.
|
||||
- More information on bot-logic that can be controlled with comments is [here](https://github.com/OfficeDev/office-ui-fabric-react/wiki/Advanced-auto-merge)
|
||||
|
||||
#### Mark issues with an active PR
|
||||
- If there is an active PR for an issue, label that issue with the `In-PR` label
|
||||
|
||||
#### Add committed fix tag for completed PRs
|
||||
- When a PR is finished and there's no outstanding work left on a linked issue, add the `Resolution-Fix-Committed` label
|
||||
|
||||
## Admin Panel
|
||||
[Here](https://fabric-cp.azurewebsites.net/bot/)
|
||||
|
||||
@@ -3,47 +3,45 @@
|
||||
## Globals
|
||||
Properties listed below affect the entire window, regardless of the profile settings.
|
||||
|
||||
| Property | Necessity | Type | Default | Description |
|
||||
| -------- | --------- | ---- | ------- | ----------- |
|
||||
| `alwaysShowTabs` | _Required_ | Boolean | `true` | When set to `true`, tabs are always displayed. When set to `false` and `showTabsInTitlebar` is set to `false`, tabs only appear after typing <kbd>Ctrl</kbd> + <kbd>T</kbd>. |
|
||||
| `defaultProfile` | _Required_ | String | PowerShell guid | Sets the default profile. Opens by typing <kbd>Ctrl</kbd> + <kbd>T</kbd> or by clicking the '+' icon. The guid of the desired default profile is used as the value. |
|
||||
| `initialCols` | _Required_ | Integer | `120` | The number of columns displayed in the window upon first load. |
|
||||
| `initialRows` | _Required_ | Integer | `30` | The number of rows displayed in the window upon first load. |
|
||||
| `requestedTheme` | _Required_ | String | `system` | Sets the theme of the application. Possible values: `"light"`, `"dark"`, `"system"` |
|
||||
| `showTerminalTitleInTitlebar` | _Required_ | Boolean | `true` | When set to `true`, titlebar displays the title of the selected tab. When set to `false`, titlebar displays "Windows Terminal". |
|
||||
| `showTabsInTitlebar` | Optional | Boolean | `true` | When set to `true`, the tabs are moved into the titlebar and the titlebar disappears. When set to `false`, the titlebar sits above the tabs. |
|
||||
| `wordDelimiters` | Optional | String | ` ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502` | Determines the delimiters used in a double click selection. |
|
||||
| Property | Necessity | Type | Description |
|
||||
| -------- | ---- | ----------- | ----------- |
|
||||
| `alwaysShowTabs` | _Required_ | Boolean | When set to `true`, tabs are always displayed. When set to `false` and `showTabsInTitlebar` is set to `false`, tabs only appear after typing <kbd>Ctrl</kbd> + <kbd>T</kbd>. |
|
||||
| `defaultProfile` | _Required_ | String | Sets the default profile. Opens by typing <kbd>Ctrl</kbd> + <kbd>T</kbd> or by clicking the '+' icon. The guid of the desired default profile is used as the value. |
|
||||
| `initialCols` | _Required_ | Integer | The number of columns displayed in the window upon first load. |
|
||||
| `initialRows` | _Required_ | Integer | The number of rows displayed in the window upon first load. |
|
||||
| `requestedTheme` | _Required_ | String | Sets the theme of the application. Possible values: `"light"`, `"dark"`, `"system"` |
|
||||
| `showTerminalTitleInTitlebar` | _Required_ | Boolean | When set to `true`, titlebar displays the title of the selected tab. When set to `false`, titlebar displays "Windows Terminal". |
|
||||
| `showTabsInTitlebar` | Optional | Boolean | When set to `true`, the tabs are moved into the titlebar and the titlebar disappears. When set to `false`, the titlebar sits above the tabs. |
|
||||
|
||||
## Profiles
|
||||
Properties listed below are specific to each unique profile.
|
||||
|
||||
| Property | Necessity | Type | Default | Description |
|
||||
| -------- | --------- | ---- | ------- | ----------- |
|
||||
| `acrylicOpacity` | _Required_ | Number | `0.5` | When `useAcrylic` is set to `true`, it sets the transparency of the window for the profile. Accepts floating point values from 0-1. |
|
||||
| `closeOnExit` | _Required_ | Boolean | `true` | When set to `true`, the selected tab closes when `exit` is typed. When set to `false`, the tab will remain open when `exit` is typed. |
|
||||
| `colorScheme` | _Required_ | String | `Campbell` | Name of the terminal color scheme to use. Color schemes are defined under `schemes`. |
|
||||
| `commandline` | _Required_ | String | `powershell.exe` | Executable used in the profile. |
|
||||
| `cursorColor` | _Required_ | String | `#FFFFFF` | Sets the cursor color for the profile. Uses hex color format: `"#rrggbb"`. |
|
||||
| `cursorShape` | _Required_ | String | `bar` | Sets the cursor shape for the profile. Possible values: `"vintage"` ( ▃ ), `"bar"` ( ┃ ), `"underscore"` ( ▁ ), `"filledBox"` ( █ ), `"emptyBox"` ( ▯ ) |
|
||||
| `fontFace` | _Required_ | String | `Consolas` | Name of the font face used in the profile. |
|
||||
| `fontSize` | _Required_ | Integer | `10` | Sets the font size. |
|
||||
| `guid` | _Required_ | String | | Unique identifier of the profile. Written in registry format: `"{00000000-0000-0000-0000-000000000000}"`. |
|
||||
| `historySize` | _Required_ | Integer | `9001` | The number of lines above the ones displayed in the window you can scroll back to. |
|
||||
| `name` | _Required_ | String | `PowerShell Core` | Name of the profile. Displays in the dropdown menu. |
|
||||
| `padding` | _Required_ | String | `0, 0, 0, 0` | Sets the padding around the text within the window. Can have three different formats: `"#"` sets the same padding for all sides, `"#, #"` sets the same padding for left-right and top-bottom, and `"#, #, #, #"` sets the padding individually for left, top, right, and bottom. |
|
||||
| `snapOnInput` | _Required_ | Boolean | `true` | When set to `true`, the window will scroll to the command input line when typing. When set to `false`, the window will not scroll when you start typing. |
|
||||
| `startingDirectory` | _Required_ | String | `%USERPROFILE%` | The directory the shell starts in when it is loaded. |
|
||||
| `useAcrylic` | _Required_ | Boolean | `false` | When set to `true`, the window will have an acrylic background. When set to `false`, the window will have a plain, untextured background. |
|
||||
| `background` | Optional | String | | Sets the background color of the profile. Overrides `background` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
|
||||
| `colorTable` | Optional | Array[String] | | Array of colors used in the profile if `colorscheme` is not set. Colors use hex color format: `"#rrggbb"`. Ordering is as follows: `[black, red, green, yellow, blue, magenta, cyan, white, bright black, bright red, bright green, bright yellow, bright blue, bright magenta, bright cyan, bright white]` |
|
||||
| `cursorHeight` | Optional | Integer | | Sets the percentage height of the cursor starting from the bottom. Only works when `cursorShape` is set to `"vintage"`. Accepts values from 25-100. |
|
||||
| `foreground` | Optional | String | | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
|
||||
| `icon` | Optional | String | | Image file location of the icon used in the profile. Displays within the tab and the dropdown menu. |
|
||||
| `scrollbarState` | Optional | String | | Defines the visibility of the scrollbar. Possible values: `"visible"`, `"hidden"` |
|
||||
| `tabTitle` | Optional | String | | Overrides default title of the tab. |
|
||||
| Property | Necessity | Type | Description |
|
||||
| -------- | ---- | ----------- | ----------- |
|
||||
| `acrylicOpacity` | _Required_ | Number | When `useAcrylic` is set to `true`, it sets the transparency of the window for the profile. Accepts floating point values from 0-1. |
|
||||
| `background` | _Required_ | String | Sets the background color of the profile. Overrides `background` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
|
||||
| `closeOnExit` | _Required_ | Boolean | When set to `true`, the selected tab closes when `exit` is typed. When set to `false`, the tab will remain open when `exit` is typed. |
|
||||
| `colorScheme` | _Required_ | String | Name of the terminal color scheme to use. Color schemes are defined under `schemes`. |
|
||||
| `commandline` | _Required_ | String | Executable used in the profile. |
|
||||
| `cursorColor` | _Required_ | String | Sets the cursor color for the profile. Uses hex color format: `"#rrggbb"`. |
|
||||
| `cursorShape` | _Required_ | String | Sets the cursor shape for the profile. Possible values: `"vintage"` ( ▃ ), `"bar"` ( ┃ ), `"underscore"` ( ▁ ), `"filledBox"` ( █ ), `"emptyBox"` ( ▯ ) |
|
||||
| `fontFace` | _Required_ | String | Name of the font face used in the profile. |
|
||||
| `fontSize` | _Required_ | Integer | Sets the font size. |
|
||||
| `guid` | _Required_ | String | Unique identifier of the profile. Written in registry format: `"{00000000-0000-0000-0000-000000000000}"`. |
|
||||
| `historySize` | _Required_ | Integer | The number of lines above the ones displayed in the window you can scroll back to. |
|
||||
| `name` | _Required_ | String | Name of the profile. Displays in the dropdown menu. |
|
||||
| `padding` | _Required_ | String | Sets the padding around the text within the window. Can have three different formats: `"#"` sets the same padding for all sides, `"#, #"` sets the same padding for left-right and top-bottom, and `"#, #, #, #"` sets the padding individually for left, top, right, and bottom. |
|
||||
| `snapOnInput` | _Required_ | Boolean | When set to `true`, the window will scroll to the command input line when typing. When set to `false`, the window will not scroll when you start typing. |
|
||||
| `startingDirectory` | _Required_ | String | The directory the shell starts in when it is loaded. |
|
||||
| `useAcrylic` | _Required_ | Boolean | When set to `true`, the window will have an acrylic background. When set to `false`, the window will have a plain, untextured background. |
|
||||
| `colorTable` | Optional | Array[String] | Array of colors used in the profile if `colorscheme` is not set. Colors use hex color format: `"#rrggbb"`. Ordering is as follows: `[black, red, green, yellow, blue, magenta, cyan, white, bright black, bright red, bright green, bright yellow, bright blue, bright magenta, bright cyan, bright white]` |
|
||||
| `cursorHeight` | Optional | Integer | Sets the percentage height of the cursor starting from the bottom. Only works when `cursorShape` is set to `"vintage"`. Accepts values from 25-100. |
|
||||
| `foreground` | Optional | String | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
|
||||
| `icon` | Optional | String | Image file location of the icon used in the profile. Displays within the tab and the dropdown menu. |
|
||||
| `scrollbarState` | Optional | String | Defines the visibility of the scrollbar. Possible values: `"visible"`, `"hidden"` |
|
||||
|
||||
## Schemes
|
||||
Properties listed below are specific to each color scheme. [ColorTool](https://github.com/microsoft/terminal/tree/master/src/tools/ColorTool) is a great tool you can use to create and explore new color schemes. All colors use hex color format.
|
||||
Properties listed below are specific to each color scheme. ColorTool is a great tool you can use to create and explore new color schemes. All colors use hex color format.
|
||||
|
||||
| Property | Necessity | Type | Description |
|
||||
| -------- | ---- | ----------- | ----------- |
|
||||
|
||||
@@ -1,527 +0,0 @@
|
||||
# Getting TAEF unittests to work with a C++/WinRT XAML Islands application
|
||||
|
||||
* __Author__: Mike Griese @zadjii-msft
|
||||
* __Created on__: 2019-06-06
|
||||
|
||||
|
||||
So you've built a Win32 application that uses XAML Islands to display it's UI
|
||||
with C++/WinRT. How do you go about adding unittests to this application? I'm
|
||||
going to cover the steps that I took to get the Windows Terminal updated to be
|
||||
able to test not only our C++/WinRT components, but also pure c++ classes that
|
||||
were used in the application, and components that used XAML UI elements.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Make sure you're using at least the 2.0.190605.7 version of the CppWinRT nuget
|
||||
package. Prior to this version, there are some bugs with C++/WinRT's detection
|
||||
of static lib dependencies. You might be able to get your build working with
|
||||
Visual Studio on earlier versions, but not straight from MsBuild.
|
||||
|
||||
Also, if you're going to be running your tests in a CI build of some sort, make
|
||||
sure that your tests are running on a machine running at least Windows 18362. If
|
||||
your CI isn't running that version, then this doesn't matter at all.
|
||||
|
||||
Furthermore, you may need an updated TAEF package as well. Our CI uses the TAEF
|
||||
VsTest adapter to allow ADO to run TAEF tests in CI. However, there's a bug in
|
||||
the tests adapter that prevents it from running tests in a UAP context. The
|
||||
`10.38.190605002` TAEF is the most recent release at the time of writing,
|
||||
however, that doesn't have the fix necessary. Fortunately, the TAEF team was
|
||||
kind enough to prototype a fix for us, which is the version
|
||||
`10.38.190610001-uapadmin`, which we're using in this repo until an official
|
||||
release with the fix is available.
|
||||
|
||||
## Move the C++/WinRT implementation to a static lib
|
||||
|
||||
By default, most (newly authored) C++/WinRT components are authored as a dll
|
||||
that can be used to activate your types. However, you might have other classes
|
||||
in that binary that you want to be able to test, which aren't winrt types. If
|
||||
the implementation is sitting in a DLL, it'll be hard to write a TAEF unittest
|
||||
dll that can call the pure c++ types you've defined.
|
||||
|
||||
The first thing you're going to need to do is move the implementation of your
|
||||
winrt component from a dll to a static lib. Once you have the static lib, we'll
|
||||
be able to link it into the dll you were previously producing, as well as being
|
||||
able to link it into the dll we'll be using to test the types. Once this is
|
||||
complete, your dll project will exist as little more than some extra packaging
|
||||
for your new lib, as all your code will be built by the lib.
|
||||
|
||||
To aid in this description, I'll be referring to the projects that we changed.
|
||||
The dll project we changed to a lib was the `TerminalApp` project. From it, we
|
||||
created a new `TerminalAppLib` project, and changed `TerminalApp` to create a
|
||||
dll by linking the lib `TerminalAppLib` produced.
|
||||
|
||||
### Create the static lib project
|
||||
|
||||
We'll start by creating a new static lib project. The easiest way to do this is
|
||||
by copying your existing dll `vcxproj` file into a new file. Make sure to change
|
||||
the `ProjectGuid` and to add the new project to your `.sln` file. Then, change
|
||||
the `ConfigurationType` to `StaticLibrary`. This Lib should be responsible for
|
||||
building all of your headers, `.cpp` files, `.idl`s for your winrt types, and
|
||||
any `.xaml` files you might have.
|
||||
|
||||
You'll likely need to place this new file into a separate directory from the
|
||||
existing dll project, as C++/WinRT uses the project directory as the root of the
|
||||
intermediate build tree. Each directory should only have one `.vcxproj` file in
|
||||
it. For the Terminal project, we created a subdirectory `lib/` underneath
|
||||
`TerminalApp/`, and updated the `Include` paths to properly point at the
|
||||
original files. You could alternatively put all the source in one directory, and
|
||||
have separate `dll/` and `lib/` subdirectories from the source that are solely
|
||||
responsible for building their binary.
|
||||
|
||||
At this point, you might face some difficulty including the right wimnd
|
||||
references, especially from other C++/WinRT dependencies for this project that
|
||||
exist in your solution. I don't know why, but I had a fair amount of difficulty
|
||||
using a `ProjectReference` from a C++/WinRT StaticLibrary to another C++/WinRT
|
||||
project in my solution. If you're referring to any other projects, you'll need
|
||||
to set up a reference to their built `.winmd`'s manually.
|
||||
|
||||
As an example, here's how we've added a reference to the `TerminalSettings`
|
||||
project from our `TerminalAppLib` project:
|
||||
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<!-- Manually add references to each of our dependent winmds. Mark them as
|
||||
private=false and CopyLocalSatelliteAssemblies=false, so that we don't
|
||||
propogate them upwards (which can make referencing this project result in
|
||||
duplicate type definitions)-->
|
||||
|
||||
<Reference Include="Microsoft.Terminal.Settings">
|
||||
<HintPath>$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\Microsoft.Terminal.Settings.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
The `HintPath` may be different depending on your project structure - verify
|
||||
locally the right path to the `.winmd` file you're looking for.
|
||||
|
||||
Notably, you'll also need to put a `pch.h` and `pch.cpp` in the new lib's
|
||||
directory, and use them instead of the `pch.h` used by the dll. C++/WinRT will be
|
||||
very angry with you if you try to use a `pch.h` in another directory. Since
|
||||
we're putting all the code into the static lib project, take your existing
|
||||
`pch.h` and move it to the lib project's directory and create an empty `pch.h`
|
||||
in the dll project's directory.
|
||||
|
||||
### Update the dll project
|
||||
|
||||
Now that we havea lib that builds all your code, we can go ahead and tear out
|
||||
most of the dead code from the old dll project. Remove all the source files from
|
||||
the dll's `.vcxproj` file, save for the `pch.h` and `pch.cpp` files. You _may_
|
||||
need to leave the headers for any C++/WinRT types you've authored in this project
|
||||
- I'm not totally sure it's necessary.
|
||||
|
||||
Now, to link the static lib we've created. For whatever reason, adding a
|
||||
`ProjectReference` to the static lib doesn't work. So, we'll need to manually
|
||||
link the lib from the lib project. You can do that by adding the lib's output
|
||||
dir to your `AdditionalLibraryDirectories`, and adding the lib to your
|
||||
`AdditionalDependencies`, like so:
|
||||
|
||||
```xml
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<!-- Manually link with the TerminalAppLib.lib we've built. -->
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\$(Platform)\$(Configuration)\TerminalAppLib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
|
||||
<AdditionalDependencies>TerminalAppLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
```
|
||||
|
||||
We are NOT adding a reference to the static lib project's .winmd here. As of the
|
||||
2.0.190605.7 CppWinRT nuget package, this is enough for MsBuild and Visual
|
||||
Studio to be able to determine that the static lib's `.winmd` should be included
|
||||
in this package.
|
||||
|
||||
At this point, you might have some mdmerge errors, which complain about
|
||||
duplicate types in one of your dependencies. This might especially happen if one
|
||||
of your dependencies (ex `A.dll`) is also a dependency for one of your _other_
|
||||
dependencies (ex `B.dll`). In this example, your final output project `C.dll`
|
||||
depends on both `A.dll` and `B.dll`, and `B.dll` _also_ depends on `A.dll`. If
|
||||
you're seeing this, I recommend adding `Private=false` and
|
||||
`CopyLocalSatelliteAssemblies=false` to your dependent dlls. In this example,
|
||||
add similar code to `B.dll`:
|
||||
|
||||
```xml
|
||||
<ProjectReference Include="$(SolutionDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj">
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
```
|
||||
|
||||
where `TerminalSettings` is your `A.dll`, which is included by both `B` and `C`.
|
||||
|
||||
We additionally had an `.exe` project that was including our `TerminalApp`
|
||||
project, and all its `.xbf` and `.pri` files. If you have a similar project
|
||||
aggregating all your resources, you might need to update the paths to point to
|
||||
the new static lib project.
|
||||
|
||||
At this point, you should be able to rebuild your solution, and everything
|
||||
should be working just the same as before.
|
||||
|
||||
|
||||
## Add TAEF Tests
|
||||
|
||||
Now that you have a static library project, you can start building your unittest
|
||||
dll. Start by creating a new directory for your unittest code, and creating a
|
||||
`.vcxproj` for a TAEF unittest dll. For the Terminal solution, we use the TAEF
|
||||
nuget package `Taef.Redist.Wlk`.
|
||||
|
||||
### Referencing your C++/WinRT static lib
|
||||
|
||||
This step is the easiest. Add a `ProjectReference` to your static lib project,
|
||||
and your lib will be linked into your unittest dll.
|
||||
|
||||
```xml
|
||||
<ProjectReference Include="$(SolutionDir)\src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" />
|
||||
```
|
||||
|
||||
Congratulations, you can now instantiate the pure c++ types you've authored in
|
||||
your static lib. But what if you want to test your C++/WinRT types too?
|
||||
|
||||
### Using your C++/WinRT types
|
||||
|
||||
To be able to instantiate your C++/WinRT types in a TAEF unittest, you'll need
|
||||
to rely on a new feature to Windows in version 1903 which enables unpackaged
|
||||
activation of WinRT types. To do this, we'll need to author a SxS manifest that
|
||||
lists each of our types, and include it in the dll, and also activate it
|
||||
manually from TAEF.
|
||||
|
||||
#### Creating the manifest
|
||||
|
||||
First, you need to create a manifest file that lists each dll your test depends
|
||||
upon, and each of the types in that dll. For example, here's an excerpt from the
|
||||
Terminal's manifest:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<file name="TerminalSettings.dll" hashalg="SHA1">
|
||||
<activatableClass name="Microsoft.Terminal.Settings.KeyChord" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
<activatableClass name="Microsoft.Terminal.Settings.TerminalSettings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
</file>
|
||||
<file name="TerminalApp.dll" hashalg="SHA1">
|
||||
<activatableClass name="TerminalApp.App" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
<activatableClass name="TerminalApp.AppKeyBindings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
<activatableClass name="TerminalApp.XamlmetaDataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
</file>
|
||||
</assembly>
|
||||
```
|
||||
|
||||
Here we have two dlls that we depend upon, `TerminalSettings.dll` and
|
||||
`TerminalApp.dll`. `TerminalSettings` implements two types,
|
||||
`Microsoft.Terminal.Settings.KeyChord` and
|
||||
`Microsoft.Terminal.Settings.TerminalSettings`.
|
||||
|
||||
#### Linking the manifest to the test dll
|
||||
|
||||
Now that we have a manifest file, we need to embed it in your unittest dll. This
|
||||
is done with the following properties in your `vcxproj` file:
|
||||
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="TerminalApp.Unit.Tests.manifest" />
|
||||
</ItemGroup>
|
||||
```
|
||||
where `TerminalApp.Unit.Tests.manifest` is the name of your manifest file.
|
||||
|
||||
Additionally, you'll need to binplace the manifest _adjacent to your test
|
||||
binary_, so TAEF can find it at runtime. I've done this in the following way,
|
||||
though I'm sure there's a better way:
|
||||
|
||||
```xml
|
||||
<ItemDefinitionGroup>
|
||||
<PostBuildEvent>
|
||||
<!-- Manually copy the manifest to our outdir, because the test will need
|
||||
to find it adjacent to us. -->
|
||||
<Command>
|
||||
(xcopy /Y "$(OpenConsoleDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest" "$(OutDir)\TerminalApp.Unit.Tests.manifest*" )
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
```
|
||||
|
||||
#### Copying your dependencies
|
||||
|
||||
Additionally, any dlls that implement any types your test is dependent upon will
|
||||
also need to be in the output directory for the test. Manually copy those DLLs
|
||||
to the tests' output directory too. The updated `PostBuildEvent` looks like
|
||||
this:
|
||||
|
||||
```xml
|
||||
<ItemDefinitionGroup>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
echo OutDir=$(OutDir)
|
||||
(xcopy /Y "$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest" "$(OutDir)\TerminalApp.Unit.Tests.manifest*" )
|
||||
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalConnection\TerminalConnection.dll" "$(OutDir)\TerminalConnection.dll*" )
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\TerminalSettings.dll" "$(OutDir)\TerminalSettings.dll*" )
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalControl\TerminalControl.dll" "$(OutDir)\TerminalControl.dll*" )
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
```
|
||||
|
||||
Again, verify the correct paths to your dependant C++/WinRT dlls, as they may be
|
||||
different than the above
|
||||
|
||||
#### Activating the manifest from TAEF
|
||||
|
||||
Now that the manifest lives adjacent to your test dll, and all your dependent
|
||||
dlls are also adjacent to the unittest dll, there's only one thing left to do.
|
||||
TAEF will not use your dll's manifest by default, so you'll need to add a
|
||||
property to your test class/method to tell TAEF to do so. You can do this with
|
||||
the following:
|
||||
|
||||
```c++
|
||||
class SettingsTests
|
||||
{
|
||||
// Use a custom manifest to ensure that we can activate winrt types from
|
||||
// our test. This property will tell taef to manually use this as the
|
||||
// sxs manifest during this test class. It includes all the C++/WinRT
|
||||
// types we've defined, so if your test is crashing for an unknown
|
||||
// reason, make sure it's included in that file.
|
||||
BEGIN_TEST_CLASS(SettingsTests)
|
||||
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
|
||||
END_TEST_CLASS()
|
||||
|
||||
// Other Test code here
|
||||
}
|
||||
```
|
||||
|
||||
Now, if you try to add any test methods that instantiate WinRT types you've
|
||||
authored, they'll work. That is of course, so long as they don't use XAML. If
|
||||
you want to use any XAML types, then you'll have to keep reading.
|
||||
|
||||
### Using Xaml Types (with XAML Islands)
|
||||
|
||||
To be able to instatiate XAML types in your unittest, we'll need to make use of
|
||||
the [XAML Hosting
|
||||
API](https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/using-the-xaml-hosting-api)
|
||||
(Xaml Islands). This enables you to use XAML APIs from a Win32 context.
|
||||
|
||||
|
||||
#### Adding XAML Hosting code
|
||||
|
||||
First and foremost, you'll need to add the following to your test's `precomp.h`:
|
||||
|
||||
```c++
|
||||
#include <winrt/Windows.system.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.UI.Xaml.Hosting.h>
|
||||
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
|
||||
```
|
||||
|
||||
If you hit a compile warning that refers to `GetCurrentTime`, you'll probably
|
||||
also need the following, after you've `#include`'d `Windows.h`:
|
||||
|
||||
```c++
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
```
|
||||
|
||||
Then, somewhere in your test code, you'll need to start up Xaml Islands. I've done this in my `TEST_CLASS_SETUP`, so that I only create it once, and re-use it for each method.
|
||||
|
||||
```c++
|
||||
|
||||
class TabTests
|
||||
{
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||
// Initialize the Xaml Hosting Manager
|
||||
_manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
|
||||
_source = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager _manager{ nullptr };
|
||||
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source{ nullptr };
|
||||
```
|
||||
|
||||
#### Authoring your test's `AppxManifest.xml`
|
||||
|
||||
This alone however is not enough to get XAML Islands to work. There was a fairly
|
||||
substantial change to the XAML Hosting API around Windows build 18295, so it
|
||||
explicitly requires that you have your executable's manifest set
|
||||
`maxversiontested` to higher than that version. However, because TAEF's `te.exe`
|
||||
is not so manifested, we can't just use our SxS manifest from before to set that
|
||||
version. Instead, you'll need to make TAEF run your test binary in a packaged
|
||||
content, with our own appxmanifest.
|
||||
|
||||
To do this, we'll need to author an `Appxmanifest.xml` to use with the test, and
|
||||
associate that manifest with the test.
|
||||
|
||||
Here's the AppxManifest we're using:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap">
|
||||
|
||||
<Identity Name="TerminalApp.Unit.Tests.Package"
|
||||
ProcessorArchitecture="neutral"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="1.0.0.0"
|
||||
ResourceId="en-us" />
|
||||
<Properties>
|
||||
<DisplayName>TerminalApp.Unit.Tests.Package Host Process</DisplayName>
|
||||
<PublisherDisplayName>Microsoft Corp.</PublisherDisplayName>
|
||||
<Logo>taef.png</Logo>
|
||||
<Description>TAEF Packaged Cwa FullTrust Application Host Process</Description>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="TE.ProcessHost" Executable="TE.ProcessHost.exe" EntryPoint="Windows.FullTrustApplication">
|
||||
<uap:VisualElements DisplayName="TAEF Packaged Cwa FullTrust Application Host Process" Square150x150Logo="taef.png" Square44x44Logo="taef.png" Description="TAEF Packaged Cwa Application Host Process" BackgroundColor="#222222">
|
||||
<uap:SplashScreen Image="taef.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust"/>
|
||||
</Capabilities>
|
||||
|
||||
<Extensions>
|
||||
<Extension Category="windows.activatableClass.inProcessServer">
|
||||
<InProcessServer>
|
||||
<Path>TerminalSettings.dll</Path>
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.TerminalSettings" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.KeyChord" ThreadingModel="both" />
|
||||
</InProcessServer>
|
||||
</Extension>
|
||||
<!-- More extensions here -->
|
||||
</Extensions>
|
||||
</Package>
|
||||
```
|
||||
|
||||
Change the `Identity.Name` and `Properties.DisplayName` to be more appropriate
|
||||
for your test, as well as other properties if you feel the need. TAEF will
|
||||
deploy the test package and remove it from your machine during testing, so it
|
||||
doesn't terribly matter what these values are.
|
||||
|
||||
MAKE SURE that `MaxVersionTested` is higher than `10.0.18295.0`. If it isn't,
|
||||
XAML islands will still prevent you from activating it.
|
||||
|
||||
UNDER NO CIRCUMSTANCE should you change the `<Application Id="TE.ProcessHost"
|
||||
Executable="TE.ProcessHost.exe" EntryPoint="Windows.FullTrustApplication">`
|
||||
line. This is how TAEF activates the TAEF host for your test binary. You might
|
||||
get a warning about `TE.ProcessHost.exe` being deprecated in favor of
|
||||
`TE.ProcessHost.UAP.exe`, but I haven't had success with the UAP version.
|
||||
|
||||
Lower in the file, you'll see the `Extensions` block. In here you'll put each of
|
||||
the winrt dependencies that your test needs, much like we did for the previous
|
||||
manifest. Note that the syntax is _not_ exactly the same as the SxS manifest.
|
||||
|
||||
#### Copy the AppxManifest to your `$(OutDir)`
|
||||
|
||||
Again, we'll need to copy this appxmanifest adjacent to the test binary so we
|
||||
can load it from the test. We'll do this similar to how we did the SxS manifest
|
||||
before. The complete `PostBuildEvent` now looks like this:
|
||||
|
||||
```xml
|
||||
<ItemDefinitionGroup>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
(xcopy /Y "$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest" "$(OutDir)\TerminalApp.Unit.Tests.manifest*" )
|
||||
|
||||
(xcopy /Y "$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.AppxManifest.xml" "$(OutDir)\TerminalApp.Unit.Tests.AppxManifest.xml*" )
|
||||
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalConnection\TerminalConnection.dll" "$(OutDir)\TerminalConnection.dll*" )
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\TerminalSettings.dll" "$(OutDir)\TerminalSettings.dll*" )
|
||||
(xcopy /Y "$(SolutionDir)$(Platform)\$(Configuration)\TerminalControl\TerminalControl.dll" "$(OutDir)\TerminalControl.dll*" )
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
```
|
||||
|
||||
The new line here is the line referencing
|
||||
`TerminalApp.Unit.Tests.AppxManifest.xml`. You can only have one
|
||||
`PostBuildEvent` per project, so don't go re-defining it for each additional
|
||||
step - MsBuild will only use the last one. Again, this is probably not the best
|
||||
way of copying these files over, but it works.
|
||||
|
||||
#### Use the AppxManifest in the test code
|
||||
|
||||
Now that we have the AppxManifest being binplaced next to our test, we can
|
||||
finally reference it in the test. Instead of using the `ActivationContext` from
|
||||
before, we'll use two new properties to tell TAEF to run this test as a package,
|
||||
and to use our manifest as the AppxManifest for the package.
|
||||
|
||||
```c++
|
||||
BEGIN_TEST_CLASS(TabTests)
|
||||
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
|
||||
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TerminalApp.Unit.Tests.AppxManifest.xml")
|
||||
END_TEST_CLASS()
|
||||
```
|
||||
|
||||
The complete Xaml Hosting test now looks like this:
|
||||
|
||||
```c++
|
||||
class TabTests
|
||||
{
|
||||
BEGIN_TEST_CLASS(TabTests)
|
||||
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
|
||||
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TerminalApp.Unit.Tests.AppxManifest.xml")
|
||||
END_TEST_CLASS()
|
||||
|
||||
TEST_METHOD(TryCreateXamlObjects);
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||
// Initialize the Xaml Hosting Manager
|
||||
_manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
|
||||
_source = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager _manager{ nullptr };
|
||||
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source{ nullptr };
|
||||
};
|
||||
void TabTests::TryCreateXamlObjects(){ ... }
|
||||
```
|
||||
|
||||
Congratulations, you can now use XAML types from your unittest.
|
||||
|
||||
### Using types from `Microsoft.UI.Xaml`
|
||||
|
||||
Let's say you're extra crazy and you're using the `Microsoft.UI.Xaml` nuget
|
||||
package. If you've followed all the steps above exactly, you're probably already
|
||||
fine! You've already put the types in your appxmanifest (there are a lot of
|
||||
them). You should be able to call the `Microsoft.UI.Xaml` types without any
|
||||
problems.
|
||||
|
||||
This is because of a few key lines we already put in the appxmanifest:
|
||||
|
||||
```xml
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
||||
</Dependencies>
|
||||
```
|
||||
|
||||
Without these `PackageDependency` entries for the VCLibs, Microsoft.UI.Xaml.dll
|
||||
will not be able to load.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,78 +0,0 @@
|
||||
---
|
||||
author: Pankaj Bhojwani pankaj.d.bhoj@gmail.com
|
||||
created on: 2019-06-12
|
||||
last updated: 2019-06-12
|
||||
issue id: #1235
|
||||
---
|
||||
|
||||
# Azure cloud shell connector
|
||||
|
||||
## Abstract
|
||||
|
||||
This spec goes over the details of how a feature enabling Windows Terminal users to connect to the Azure cloud shell should behave. It includes implementation and design considerations.
|
||||
|
||||
## Inspiration
|
||||
|
||||
The idea is to give developers access to their Azure services smoothly within the Windows Terminal app, letting them engage with Azure technologies in a convenient manner. By integrating the Azure cloud shell into Windows Terminal, we can do just that.
|
||||
|
||||
## Solution Design
|
||||
|
||||
The flowchart below shows the process by which the Azure cloud shell will be integrated into Windows Terminal.
|
||||
|
||||

|
||||
|
||||
The first three steps - authenticating the user, requesting a cloud shell and requesting a terminal - will be done via http requests. These requests will use the [cpprestsdk](https://github.com/Microsoft/cpprestsdk) library as that library is also owned by Microsoft, making it easy to resolve issues should any arise.
|
||||
|
||||
Authenticating the user will use [device code flow](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Device-Code-Flow) since Windows Terminal does not support browser access (yet). As for the authentication endpoint, Azure AD v1.0 will be used because Azure AD v2.0 (also known as Microsoft Identity Platform) [does not support login to personal accounts with device code flow](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Device-Code-Flow#constraints) at this time. Furthermore, upon successful authentication, the login/token information will be stored so that users will not need to repeatedly go through device code flow for future logins. Since this is sensitive information, the tokens will be stored with [Windows Storage](https://docs.microsoft.com/en-us/uwp/api/windows.storage) and encrypted with [Windows Security Data Protection](https://docs.microsoft.com/en-us/uwp/api/windows.security.cryptography.dataprotection.dataprotectionprovider).
|
||||
|
||||
The last step - connecting to the terminal - will be done via a websocket connection to allow easier communication between the app and the server.
|
||||
|
||||
The entire feature will be implemented in an isolated manner - i.e. it should have little to no dependency on the Windows Terminal app itself. This will allow the feature to become a plugin/extension once Windows Terminal supports plugins. More specifically, the connector will ascribe to the existing ITerminalConnection interface, making this simply another type of connection that Windows Terminal can make.
|
||||
|
||||
## UI/UX Design
|
||||
|
||||
Upon successful implementation, a new profile option will appear for users as illustrated in the picture below (the profile will have its own unique icon when implemented).
|
||||
|
||||

|
||||
|
||||
As for the rest of the UI, the implementation will adopt the user's preferences from the Windows Terminal app.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Accessibility
|
||||
|
||||
This feature will not impact accessibility of Windows Terminal.
|
||||
|
||||
### Security
|
||||
|
||||
Any feature that connects to a network introduces some security risks. However, with proper usage of Azure AD v1.0 and careful storage of tokens received from the server, these risks will be mitigated.
|
||||
|
||||
### Reliability
|
||||
|
||||
This feature will not impact reliability of Windows Terminal.
|
||||
|
||||
### Compatibility
|
||||
|
||||
With the implementation being mostly decoupled from the Windows Terminal app itself, no existing code/behaviours should break due to this feature.
|
||||
|
||||
### Performance, Power, and Efficiency
|
||||
|
||||
This feature will not impact performance, power or efficiency of Windows Terminal.
|
||||
|
||||
## Potential Issues
|
||||
|
||||
1. This implementation depends on another open source project, [cpprestsdk](https://github.com/Microsoft/cpprestsdk). Thus, any issues with their code will affect this feature. However, given that cpprestsdk is a Microsoft project, we can expect a level of reliability and also solve issues internally if needed.
|
||||
2. The proposed authentication endpoint is Azure AD v1.0 instead of Azure AD v2.0 (also known as Microsoft Identity Platform). Azure AD v1.0 is still supported for now, but there is a risk of it becoming deprecated at some point in the future. However, given that it is once again another Microsoft-owned project, we can request support for it through an internal channel. In the worst case, our implementation can switch to Microsoft Identity Platform (which would only requires some minor edits to the http requests).
|
||||
3. The Azure cloud shell API is not public, meaning that implementing this feature in an official capacity would require app permissions from the Azure cloud shell team. This brings about another dependency, but once again issues can be resolved through internal Microsoft channels.
|
||||
|
||||
## Future considerations
|
||||
|
||||
This could potentially be the first plugin for Windows Terminal once the app allows for plugins/extensions!
|
||||
|
||||
## Resources
|
||||
|
||||
* [Azure AD v1.0](https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-overview)
|
||||
* [cpprestsdk](https://github.com/Microsoft/cpprestsdk)
|
||||
* [Device code flow](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Device-Code-Flow)
|
||||
* [Windows Storage](https://docs.microsoft.com/en-us/uwp/api/windows.storage)
|
||||
* [Windows Security Data Protection](https://docs.microsoft.com/en-us/uwp/api/windows.security.cryptography.dataprotection.dataprotectionprovider)
|
||||
@@ -1,128 +0,0 @@
|
||||
# Editing Windows Terminal JSON Settings
|
||||
|
||||
One way (currently the only way) to configure Windows Terminal is by editing the profiles.json settings file. At
|
||||
the time of writing you can open the settings file in your default editor by selecting
|
||||
`Settings` from the WT pull down menu.
|
||||
|
||||
The settings are stored in the file `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_<randomString>\RoamingState\profiles.json`
|
||||
|
||||
Details of specific settings can be found [here](../cascadia/SettingsSchema.md). A general introduction is provided below.
|
||||
|
||||
The settings are grouped under four headings:
|
||||
|
||||
1. Global: Settings that apply to the whole application e.g. Default profile, initial size etc.
|
||||
2. Key Bindings: Actually a sub field of the global settings, but worth discussing separately
|
||||
3. Profiles: A group of settings to be applied to a tab when it is opened using that profile. E.g. shell to use, cursor shape etc.
|
||||
4. Schemes: Sets of colors for background, text etc. that can be used by profiles
|
||||
|
||||
## Global Settings
|
||||
|
||||
These settings define startup defaults.
|
||||
|
||||
* Theme
|
||||
* Title Bar options
|
||||
* Initial size
|
||||
* Default profile used when WT is started
|
||||
|
||||
Example settings include
|
||||
|
||||
```json
|
||||
"defaultProfile" : "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
|
||||
"initialCols" : 120,
|
||||
"initialRows" : 50,
|
||||
"requestedTheme" : "system",
|
||||
"keybinding" : []
|
||||
...
|
||||
```
|
||||
|
||||
## Key Bindings
|
||||
|
||||
This is an array of key chords and shortcuts to invoke various commands.
|
||||
Each command can have more than one key binding.
|
||||
|
||||
NOTE: Key bindings is a subfield of the global settings and
|
||||
key bindings apply to all profiles in the same manner.
|
||||
|
||||
## Profiles
|
||||
|
||||
A profile contains the settings applied when a new WT tab is opened. Each profile is identified by a GUID and contains
|
||||
a number of other fields.
|
||||
|
||||
* Which command to execute on startup - this can include arguments.
|
||||
* Starting directory
|
||||
* Which color scheme to use (see Schemes below)
|
||||
* Font face and size
|
||||
* Various settings to control appearance. E.g. Opacity, icon, cursor appearance, display name etc.
|
||||
* Other behavioural settings. E.g. Close on exit, snap on input, .....
|
||||
|
||||
Example settings include
|
||||
|
||||
```json
|
||||
"closeOnExit" : true,
|
||||
"colorScheme" : "Campbell",
|
||||
"commandline" : "wsl.exe -d Debian",
|
||||
"cursorColor" : "#FFFFFF",
|
||||
"cursorShape" : "bar",
|
||||
"fontFace" : "Hack",
|
||||
"fontSize" : 9,
|
||||
"guid" : "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
|
||||
"name" : "Debian",
|
||||
"startingDirectory" : "%USERPROFILE%/wslhome"
|
||||
....
|
||||
```
|
||||
|
||||
The profile GUID is used to reference the default profile in the global settings.
|
||||
|
||||
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch)
|
||||
|
||||
## Color Schemes
|
||||
|
||||
Each scheme defines the color values to be used for various terminal escape sequences.
|
||||
Each schema is identified by the name field. Examples include
|
||||
|
||||
```json
|
||||
"name" : "Campbell",
|
||||
"background" : "#0C0C0C",
|
||||
"black" : "#0C0C0C",
|
||||
"blue" : "#0037DA",
|
||||
"foreground" : "#F2F2F2",
|
||||
"green" : "#13A10E",
|
||||
"red" : "#C50F1F",
|
||||
"white" : "#CCCCCC",
|
||||
"yellow" : "#C19C00"
|
||||
...
|
||||
```
|
||||
|
||||
The schema name can then be referenced in one or more profiles.
|
||||
|
||||
## Configuration Examples:
|
||||
|
||||
### Add a custom background to the WSL Debian terminal profile
|
||||
|
||||
1. Download the Debian SVG logo https://www.debian.org/logos/openlogo.svg
|
||||
2. Put the image in the
|
||||
`$env:LocalAppData\Packages\Microsoft.WindowsTerminal_<randomString>\RoamingState\`
|
||||
directory (same directory as your `profiles.json` file).
|
||||
|
||||
__NOTE__: You can put the image anywhere you like, the above suggestion happens to be convenient.
|
||||
3. Open your WT json properties file.
|
||||
4. Under the Debian Linux profile, add the following fields:
|
||||
```json
|
||||
"backgroundImage": "ms-appdata:///Roaming/openlogo.jpg",
|
||||
"backgroundImageOpacity": 0.3,
|
||||
"backgroundImageStretchMode": "Fill",
|
||||
```
|
||||
5. Make sure that `useAcrylic` is `false`.
|
||||
6. Save the file.
|
||||
7. Jump over to WT and verify your changes.
|
||||
|
||||
Notes:
|
||||
1. You will need to experiment with different color settings
|
||||
and schemes to make your terminal text visible on top of your image
|
||||
2. If you store the image in the UWP directory (the same directory as your profiles.json file),
|
||||
then you should use the URI style path name given in the above example.
|
||||
More information about UWP URI schemes [here](https://docs.microsoft.com/en-us/windows/uwp/app-resources/uri-schemes).
|
||||
3. Instead of using a UWP URI you can use a:
|
||||
1. URL such as
|
||||
`http://open.esa.int/files/2017/03/Mayer_and_Bond_craters_seen_by_SMART-1-350x346.jpg`
|
||||
2. Local file location such as `C:\Users\Public\Pictures\openlogo.jpg`
|
||||
@@ -1,90 +0,0 @@
|
||||
# Windows Terminal User Documentation
|
||||
|
||||
NOTE: At the time of writing Windows Terminal is still under active development and many things will
|
||||
change. If you notice an error in the docs, please raise an issue. Or better yet, please file a PR with an appropriate update!
|
||||
|
||||
## Installing Windows Terminal
|
||||
|
||||
### From Source Code
|
||||
|
||||
Follow the instructions in this repo's [README](/README.md#developer-guidance).
|
||||
|
||||
### From the Microsoft Store
|
||||
|
||||
1. Make sure you have upgraded to the current Windows 10 release (at least 1903)
|
||||
2. Search for Windows Terminal in the Store
|
||||
3. Review the minimum system settings to ensure you can successfully install Windows Terminal
|
||||
4. Install in the normal fashion
|
||||
|
||||
## Starting Windows Terminal
|
||||
|
||||
From the Windows Start menu, select Windows Terminal and run the application.
|
||||
|
||||
Note: You can right click on the application item and run with Windows Administrator privilege if required.
|
||||
|
||||
The default shell is PowerShell.
|
||||
|
||||
|
||||
### Command line options
|
||||
|
||||
None at this time. See issue [#607](https://github.com/microsoft/terminal/issues/607)
|
||||
|
||||
## Multiple Tabs
|
||||
|
||||
Additional shells can be started by hitting the `+` button from the tab bar -- a new instance of the
|
||||
default shell is displayed (default shortcut `Ctrl+Shift+1`).
|
||||
|
||||
## Running a Different Shell
|
||||
|
||||
Note: The following text assumes you have WSL installed.
|
||||
|
||||
To choose a different shell (e.g. `cmd.exe` or WSL `bash`) then
|
||||
|
||||
1. Select the `down` button next to the `+` in the tab bar
|
||||
2. Choose your new shell from the list (more on how to extend the list in the config section)
|
||||
|
||||
## Starting a new PowerShell tab with admin privilege
|
||||
|
||||
There is no current plan to support this feature for security reaons. See issue [#623](https://github.com/microsoft/terminal/issues/632)
|
||||
|
||||
## Using cut and paste in the Terminal window
|
||||
|
||||
### With PowerShell
|
||||
|
||||
* Copy - Select the text with mouse (default left button), then right click with mouse
|
||||
* Paste - by default use `<ctrl>+v`>, or right click with mouse
|
||||
|
||||
### With Bash
|
||||
|
||||
* Copy - Select the text with mouse (default left button), then right click with mouse
|
||||
* Paste - Right click with mouse
|
||||
|
||||
## Add a "Open Windows Terminal Here" to File Explorer
|
||||
|
||||
Not currently supported "out of the box". See issue [#1060](https://github.com/microsoft/terminal/issues/1060)
|
||||
|
||||
## Configuring Windows Terminal
|
||||
|
||||
At the time of writing all Windows Terminal settings are managed via a json file.
|
||||
|
||||
From the `down` button in the top bar select Settings (default shortcut `Ctrl+,`).
|
||||
|
||||
Your default json editor will open up the Terminal settings file. The file can be found
|
||||
at `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_<randomString>/RoamingState`
|
||||
|
||||
An introduction to the the various settings can be found [here](UsingJsonSettings.md).
|
||||
|
||||
The list of valid settings can be found in the [Profiles.json Documentation](../cascadia/SettingsSchema.md) doc.
|
||||
|
||||
## Tips and Tricks:
|
||||
|
||||
1. In PowerShell you can discover if the Windows Terminal is being used by checking for the existence of the environment variable `WT_SESSION`.
|
||||
|
||||
Under pwsh you can also use
|
||||
`(Get-Process -Id $pid).Parent.Parent.ProcessName -eq 'WindowsTerminal'`
|
||||
|
||||
(ref https://twitter.com/r_keith_hill/status/1142871145852440576)
|
||||
|
||||
2. Terminal zoom can be changed by holding `Ctrl` and scrolling with mouse.
|
||||
3. If `useAcrylic` is enabled in profiles.json, background opacity can be changed by holding `Ctrl+Shift` and scrolling with mouse.
|
||||
4. Please add more Tips and Tricks
|
||||
@@ -1,15 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
|
||||
|
||||
<PropertyGroup Label="Version">
|
||||
<!-- These fields are picked up by PackageES -->
|
||||
<VersionMajor>0</VersionMajor>
|
||||
<VersionMinor>2</VersionMinor>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Configuration">
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
|
||||
<TargetPlatformVersion>10.0.17763.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<!--
|
||||
These two properties are very important!
|
||||
Without them, msbuild will stomp MinVersion and MaxVersionTested in the
|
||||
@@ -19,23 +22,27 @@
|
||||
<AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
|
||||
<AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>CA5CAD1A-224A-4171-B13A-F16E576FDD12</ProjectGuid>
|
||||
<EntryPointProjectUniqueName>..\WindowsTerminal\WindowsTerminal.vcxproj</EntryPointProjectUniqueName>
|
||||
<DebuggerType>NativeOnly</DebuggerType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="!Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<PackageCertificateKeyFile>CascadiaPackage_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<None Include="CascadiaPackage_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest" Condition="'$(WindowsTerminalReleaseBuild)'=='true'">
|
||||
<SubType>Designer</SubType>
|
||||
@@ -44,6 +51,7 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="$(OpenConsoleDir)res\terminal\LargeTile.scale-100.png">
|
||||
<Link>Images\LargeTile.scale-100.png</Link>
|
||||
@@ -259,65 +267,62 @@
|
||||
<Content Include="ProfileIcons\{9acb9455-ca41-5af7-950f-6bca1bc9722f}.scale-200.png" />
|
||||
<PRIResource Include="Resources\en-US\Resources.resw" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />
|
||||
<!--
|
||||
Microsoft.UI.Xaml contains some <Content> resource files that need to be included in our package.
|
||||
For some reason, they're not rolled up through dependent projects; if they were, their paths would
|
||||
be wrong.
|
||||
|
||||
WAP Packaging projects don't actually support nuget package references, so we added one manually.
|
||||
<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />
|
||||
|
||||
<!--
|
||||
This exists to work around Microsoft/microsoft-ui-xaml#494.
|
||||
https://github.com/Microsoft/microsoft-ui-xaml/issues/494
|
||||
|
||||
Because the MUX nuget package hardcodes a requirement that the consuming project
|
||||
be of type 'UAP', its resources are included in packaging and dependency resolution
|
||||
by default. Inject them here.
|
||||
|
||||
This does mean that version changes to Microsoft.UI.Xaml must be manually reflected
|
||||
here.
|
||||
-->
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<WapProjBeforeGenerateAppxManifestDependsOn>
|
||||
$(WapProjBeforeGenerateAppxManifestDependsOn);
|
||||
_ConsoleInjectMUXWinmdIntoReferences;
|
||||
</WapProjBeforeGenerateAppxManifestDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="_ConsoleInjectMUXWinmdIntoReferences">
|
||||
<ItemGroup>
|
||||
<_WinmdFilesFromReferences Include="@(Reference)" Condition="'%(Reference.Filename)' == 'Microsoft.UI.Xaml' and '%(Reference.Extension)' == '.winmd'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<!-- End workaround -->
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
|
||||
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Stomp the path to conhost.exe.
|
||||
This task will copy OpenConsole.exe to the appx as conhost.exe, and place it
|
||||
adjacent to WindowsTerminal.exe.
|
||||
-->
|
||||
<Target Name="OpenConsoleStompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
|
||||
<ItemGroup>
|
||||
<Target Name="OpenConsoleStompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
|
||||
<ItemGroup>
|
||||
<!-- Stomp all "SourceProject" values for all incoming dependencies to flatten the package. -->
|
||||
<_TemporaryFilteredWapProjOutput Include="@(_FilteredNonWapProjProjectOutput)" />
|
||||
<_FilteredNonWapProjProjectOutput Remove="@(_TemporaryFilteredWapProjOutput)" />
|
||||
<_FilteredNonWapProjProjectOutput Include="@(_TemporaryFilteredWapProjOutput)">
|
||||
<_TemporaryFilteredWapProjOutput
|
||||
Include="@(_FilteredNonWapProjProjectOutput)" />
|
||||
<_FilteredNonWapProjProjectOutput Remove="@(_TemporaryFilteredWapProjOutput)" />
|
||||
<_FilteredNonWapProjProjectOutput Include="@(_TemporaryFilteredWapProjOutput)">
|
||||
<!-- Override the filename for OpenConsole.exe (only) -->
|
||||
<TargetPath Condition="'%(Filename)' == 'OpenConsole' and '%(Extension)' == '.exe'">conhost.exe</TargetPath>
|
||||
<!-- Blank the SourceProject here to vend all files into the root of the package. -->
|
||||
<SourceProject></SourceProject>
|
||||
</_FilteredNonWapProjProjectOutput>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- Move all the PRI files that would be packaged into the appx into _PriFile so that
|
||||
GenerateProjectPriFile catches them. This requires us to move payload collection
|
||||
up before GenerateProjectPriFile, when it is typically _after_ it (because the
|
||||
DesktopBridge project type is built to only prepare the payload during appx manifest
|
||||
generation.
|
||||
|
||||
Since PRI file generation is _before_ manifest generation (for possibly obvious or
|
||||
important reasons), that doesn't work for us.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<_GenerateProjectPriFileDependsOn>OpenConsoleLiftDesktopBridgePriFiles;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="OpenConsoleLiftDesktopBridgePriFiles" DependsOnTargets="_ConvertItems">
|
||||
<ItemGroup>
|
||||
<_PriFile Include="@(_NonWapProjProjectOutput)" Condition="'%(Extension)' == '.pri'" />
|
||||
<!-- Remove all other .pri files from the appx payload. -->
|
||||
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.pri'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<!-- Blank the SourceProject here to vend all files into the root of the pacakge. -->
|
||||
<SourceProject></SourceProject>
|
||||
</_FilteredNonWapProjProjectOutput>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -156,28 +156,4 @@
|
||||
<data name="AppShortNameDev" xml:space="preserve">
|
||||
<value>Terminal (Dev)</value>
|
||||
</data>
|
||||
<data name="DocumentationLabelText" xml:space="preserve">
|
||||
<value>Documentation
|
||||
</value>
|
||||
</data>
|
||||
<data name="GettingStartedLabelText" xml:space="preserve">
|
||||
<value>Getting Started
|
||||
</value>
|
||||
</data>
|
||||
<data name="ReleaseNotesLabelText" xml:space="preserve">
|
||||
<value>Release Notes
|
||||
</value>
|
||||
</data>
|
||||
<data name="DocumentationUriValue" xml:space="preserve">
|
||||
<value>https://aka.ms/terminal-documentation</value>
|
||||
</data>
|
||||
<data name="GettingStartedUriValue" xml:space="preserve">
|
||||
<value>https://aka.ms/terminal-getting-started</value>
|
||||
</data>
|
||||
<data name="ReleaseNotesUriValue" xml:space="preserve">
|
||||
<value>https://aka.ms/terminal-release-notes</value>
|
||||
</data>
|
||||
<data name="FeedbackUriValue" xml:space="preserve">
|
||||
<value>https://aka.ms/terminal-feedback</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
<!-- build a dll, not exe (Application) -->
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<!-- sets a bunch of Windows Universal properties -->
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{015a0047-772d-4f1a-88c9-45c18f0adfb6}</ProjectGuid>
|
||||
<ProjectName>Microsoft.UI.Xaml.Markup</ProjectName>
|
||||
<RootNamespace>Microsoft.UI.Xaml.Markup</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalDependencies>WindowsApp.lib;Kernel32.lib;User32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="XamlApplication.h">
|
||||
<DependentUpon>XamlApplication.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XamlApplication.cpp">
|
||||
<DependentUpon>XamlApplication.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Midl Include="XamlApplication.idl" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Microsoft.UI.Xaml.Markup.def" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="ReadMe.md" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
DON'T REDIRECT OUR OUTPUT.
|
||||
Setting this will tell cppwinrt.build.post.props to copy our output from
|
||||
the default OutDir up one level, so the wapproj will be able to find it.
|
||||
-->
|
||||
<NoOutputRedirection>true</NoOutputRedirection>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
</Project>
|
||||
22
src/cascadia/Microsoft.UI.Xaml.Markup/ReadMe.md
Normal file
22
src/cascadia/Microsoft.UI.Xaml.Markup/ReadMe.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Xaml Application for Win32
|
||||
|
||||
This project implements an Xaml application that is suited for Win32 projects.
|
||||
A pseudo implementation of this object is:
|
||||
```
|
||||
namespace Microsoft.UI.Xaml.Markup
|
||||
{
|
||||
interface IXamlMetadataProviderContainer
|
||||
{
|
||||
Windows.Foundation.Collections.IVector<Windows.UI.Xaml.Markup.IXamlMetadataProvider> Providers { get; };
|
||||
};
|
||||
|
||||
class XamlApplication : Windows.UI.Xaml.Application, IXamlMetadataProviderContainer, IDisposable
|
||||
{
|
||||
XamlApplication()
|
||||
{
|
||||
WindowsXamlManager.InitializeForThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
130
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.cpp
Normal file
130
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "XamlApplication.h"
|
||||
|
||||
#include "XamlApplication.g.cpp"
|
||||
|
||||
namespace xaml = ::winrt::Windows::UI::Xaml;
|
||||
|
||||
extern "C" {
|
||||
WINBASEAPI HMODULE WINAPI LoadLibraryExW(_In_ LPCWSTR lpLibFileName, _Reserved_ HANDLE hFile, _In_ DWORD dwFlags);
|
||||
WINBASEAPI HMODULE WINAPI GetModuleHandleW(_In_opt_ LPCWSTR lpModuleName);
|
||||
WINUSERAPI BOOL WINAPI PeekMessageW(_Out_ LPMSG lpMsg, _In_opt_ HWND hWnd, _In_ UINT wMsgFilterMin, _In_ UINT wMsgFilterMax, _In_ UINT wRemoveMsg);
|
||||
WINUSERAPI LRESULT WINAPI DispatchMessageW(_In_ CONST MSG* lpMsg);
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::UI::Xaml::Markup::implementation
|
||||
{
|
||||
XamlApplication::XamlApplication(winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider parentProvider)
|
||||
{
|
||||
m_providers.Append(parentProvider);
|
||||
}
|
||||
|
||||
XamlApplication::XamlApplication()
|
||||
{
|
||||
}
|
||||
|
||||
void XamlApplication::Close()
|
||||
{
|
||||
if (m_bIsClosed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bIsClosed = true;
|
||||
|
||||
m_providers.Clear();
|
||||
|
||||
Exit();
|
||||
{
|
||||
MSG msg = {};
|
||||
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
::DispatchMessageW(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XamlApplication::~XamlApplication()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
xaml::Markup::IXamlType XamlApplication::GetXamlType(xaml::Interop::TypeName const& type)
|
||||
{
|
||||
for (const auto& provider : m_providers)
|
||||
{
|
||||
const auto xamlType = provider.GetXamlType(type);
|
||||
if (xamlType != nullptr)
|
||||
{
|
||||
return xamlType;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
xaml::Markup::IXamlType XamlApplication::GetXamlType(winrt::hstring const& fullName)
|
||||
{
|
||||
for (const auto& provider : m_providers)
|
||||
{
|
||||
const auto xamlType = provider.GetXamlType(fullName);
|
||||
if (xamlType != nullptr)
|
||||
{
|
||||
return xamlType;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
winrt::com_array<xaml::Markup::XmlnsDefinition> XamlApplication::GetXmlnsDefinitions()
|
||||
{
|
||||
std::list<xaml::Markup::XmlnsDefinition> definitions;
|
||||
for (const auto& provider : m_providers)
|
||||
{
|
||||
auto defs = provider.GetXmlnsDefinitions();
|
||||
for (const auto& def : defs)
|
||||
{
|
||||
definitions.insert(definitions.begin(), def);
|
||||
}
|
||||
}
|
||||
|
||||
return winrt::com_array<xaml::Markup::XmlnsDefinition>(definitions.begin(), definitions.end());
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<xaml::Markup::IXamlMetadataProvider> XamlApplication::Providers()
|
||||
{
|
||||
return m_providers;
|
||||
}
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::UI::Xaml::Markup::factory_implementation
|
||||
{
|
||||
XamlApplication::XamlApplication()
|
||||
{
|
||||
// Workaround a bug where twinapi.appcore.dll and threadpoolwinrt.dll gets loaded after it has been unloaded
|
||||
// because of a call to GetActivationFactory
|
||||
const wchar_t* preloadDlls[] = {
|
||||
L"twinapi.appcore.dll",
|
||||
L"threadpoolwinrt.dll",
|
||||
};
|
||||
for (auto dllName : preloadDlls)
|
||||
{
|
||||
const auto module = ::LoadLibraryExW(dllName, nullptr, 0);
|
||||
m_preloadInstances.push_back(module);
|
||||
}
|
||||
}
|
||||
|
||||
XamlApplication::~XamlApplication()
|
||||
{
|
||||
for (auto module : m_preloadInstances)
|
||||
{
|
||||
::FreeLibrary(module);
|
||||
}
|
||||
m_preloadInstances.clear();
|
||||
}
|
||||
}
|
||||
46
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.h
Normal file
46
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XamlApplication.g.h"
|
||||
#include <winrt/Windows.UI.Xaml.Hosting.h>
|
||||
#include <winrt/Windows.UI.ViewManagement.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace winrt::Microsoft::UI::Xaml::Markup::implementation
|
||||
{
|
||||
class XamlApplication : public XamlApplicationT<XamlApplication, Windows::UI::Xaml::Markup::IXamlMetadataProvider>
|
||||
{
|
||||
public:
|
||||
XamlApplication();
|
||||
XamlApplication(winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider parentProvider);
|
||||
~XamlApplication();
|
||||
|
||||
void Close();
|
||||
|
||||
winrt::Windows::UI::Xaml::Markup::IXamlType GetXamlType(winrt::Windows::UI::Xaml::Interop::TypeName const& type);
|
||||
winrt::Windows::UI::Xaml::Markup::IXamlType GetXamlType(winrt::hstring const& fullName);
|
||||
winrt::com_array<winrt::Windows::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions();
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider> Providers();
|
||||
|
||||
private:
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider> m_providers = winrt::single_threaded_vector<Windows::UI::Xaml::Markup::IXamlMetadataProvider>();
|
||||
bool m_bIsClosed = false;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::UI::Xaml::Markup::factory_implementation
|
||||
{
|
||||
class XamlApplication : public XamlApplicationT<XamlApplication, implementation::XamlApplication>
|
||||
{
|
||||
public:
|
||||
XamlApplication();
|
||||
~XamlApplication();
|
||||
|
||||
private:
|
||||
std::vector<HMODULE> m_preloadInstances;
|
||||
};
|
||||
}
|
||||
17
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.idl
Normal file
17
src/cascadia/Microsoft.UI.Xaml.Markup/XamlApplication.idl
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.UI.Xaml.Markup
|
||||
{
|
||||
interface IXamlMetadataProviderContainer
|
||||
{
|
||||
Windows.Foundation.Collections.IVector<Windows.UI.Xaml.Markup.IXamlMetadataProvider> Providers { get; };
|
||||
};
|
||||
|
||||
[default_interface]
|
||||
unsealed runtimeclass XamlApplication : Windows.UI.Xaml.Application, IXamlMetadataProviderContainer, Windows.Foundation.IClosable
|
||||
{
|
||||
XamlApplication();
|
||||
protected XamlApplication(Windows.UI.Xaml.Markup.IXamlMetadataProvider parentProvider);
|
||||
}
|
||||
}
|
||||
4
src/cascadia/Microsoft.UI.Xaml.Markup/packages.config
Normal file
4
src/cascadia/Microsoft.UI.Xaml.Markup/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
21
src/cascadia/Microsoft.UI.Xaml.Markup/pch.h
Normal file
21
src/cascadia/Microsoft.UI.Xaml.Markup/pch.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SDKDDKVer.h>
|
||||
// Exclude rarely-used stuff from Windows headers
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
|
||||
// SDK definition of this function, so the only fix is to undef it.
|
||||
// from WinBase.h
|
||||
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
// To enable support for non-WinRT interfaces, unknwn.h must be included before any C++/WinRT headers.
|
||||
#include <unknwn.h>
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
template<typename D, typename... I>
|
||||
struct App_baseWithProvider : public App_base<D, ::winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider>
|
||||
{
|
||||
using IXamlType = ::winrt::Windows::UI::Xaml::Markup::IXamlType;
|
||||
|
||||
IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const& type)
|
||||
{
|
||||
return AppProvider()->GetXamlType(type);
|
||||
}
|
||||
|
||||
IXamlType GetXamlType(::winrt::hstring const& fullName)
|
||||
{
|
||||
return AppProvider()->GetXamlType(fullName);
|
||||
}
|
||||
|
||||
::winrt::com_array<::winrt::Windows::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions()
|
||||
{
|
||||
return AppProvider()->GetXmlnsDefinitions();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _contentLoaded{ false };
|
||||
std::shared_ptr<XamlMetaDataProvider> _appProvider;
|
||||
std::shared_ptr<XamlMetaDataProvider> AppProvider()
|
||||
{
|
||||
if (!_appProvider)
|
||||
{
|
||||
_appProvider = std::make_shared<XamlMetaDataProvider>();
|
||||
}
|
||||
return _appProvider;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename D, typename... I>
|
||||
using AppT2 = App_baseWithProvider<D, I...>;
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
|
||||
|
||||
#include "App.g.cpp"
|
||||
#include "TerminalPage.h"
|
||||
|
||||
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@@ -16,7 +15,6 @@ using namespace winrt::Windows::System;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace ::TerminalApp;
|
||||
|
||||
// Note: Generate GUID using TlgGuid.exe tool
|
||||
@@ -36,6 +34,12 @@ namespace winrt
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
App::App() :
|
||||
App(winrt::TerminalApp::XamlMetaDataProvider())
|
||||
{
|
||||
}
|
||||
|
||||
App::App(Windows::UI::Xaml::Markup::IXamlMetadataProvider const& parentProvider) :
|
||||
base_type(parentProvider),
|
||||
_settings{},
|
||||
_tabs{},
|
||||
_loadedInitialSettings{ false },
|
||||
@@ -48,8 +52,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// cause you to chase down the rabbit hole of "why is App not
|
||||
// registered?" when it definitely is.
|
||||
|
||||
// Initialize will become protected or be deleted when GH#1339 (workaround for MSFT:22116519) are fixed.
|
||||
Initialize();
|
||||
// See GH#1339. This is a workaround for MSFT:22116519
|
||||
// We need this to prevent an occasional crash on teardown
|
||||
AddRef();
|
||||
m_inner.as<::IUnknown>()->Release();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -61,13 +67,13 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void App::Create(uint64_t hWnd)
|
||||
void App::Create()
|
||||
{
|
||||
// Assert that we've already loaded our settings. We have to do
|
||||
// this as a MTA, before the app is Create()'d
|
||||
WINRT_ASSERT(_loadedInitialSettings);
|
||||
TraceLoggingRegister(g_hTerminalAppProvider);
|
||||
_Create(hWnd);
|
||||
_Create();
|
||||
}
|
||||
|
||||
App::~App()
|
||||
@@ -77,45 +83,99 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Create all of the initial UI elements of the Terminal app.
|
||||
// * Creates the tab bar, initially hidden.
|
||||
// * Creates the tab content area, which is where we'll display the tabs/panes.
|
||||
// * Initializes the first terminal control, using the default profile,
|
||||
// and adds it to our list of tabs.
|
||||
void App::_Create(uint64_t parentHwnd)
|
||||
void App::_Create()
|
||||
{
|
||||
/* !!! TODO
|
||||
This is not the correct way to host a XAML page. This exists today because we valued
|
||||
getting a .xaml over tearing out all of the terminal logic and splitting it across App
|
||||
and Page.
|
||||
The work to clarify the boundary between app global state and "terminal page" state
|
||||
is tracked in GH#1878.
|
||||
*/
|
||||
auto terminalPage = winrt::make_self<TerminalPage>();
|
||||
_root = terminalPage.as<winrt::Windows::UI::Xaml::Controls::Control>();
|
||||
_tabContent = terminalPage->TabContent();
|
||||
_tabRow = terminalPage->TabRow();
|
||||
_tabView = terminalPage->TabView();
|
||||
_newTabButton = terminalPage->NewTabButton();
|
||||
_tabView = MUX::Controls::TabView{};
|
||||
|
||||
_minMaxCloseControl = terminalPage->MinMaxCloseControl();
|
||||
_minMaxCloseControl.ParentWindowHandle(parentHwnd);
|
||||
|
||||
if (!_settings->GlobalSettings().GetShowTabsInTitlebar())
|
||||
{
|
||||
_minMaxCloseControl.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
|
||||
// Event Bindings (Early)
|
||||
_newTabButton.Click([this](auto&&, auto&&) {
|
||||
this->_OpenNewTab(std::nullopt);
|
||||
});
|
||||
_tabView.SelectionChanged({ this, &App::_OnTabSelectionChanged });
|
||||
_tabView.TabClosing({ this, &App::_OnTabClosing });
|
||||
_tabView.Items().VectorChanged({ this, &App::_OnTabItemsChanged });
|
||||
_root.Loaded({ this, &App::_OnLoaded });
|
||||
|
||||
_root = Controls::Grid{};
|
||||
|
||||
_tabRow = Controls::Grid{};
|
||||
_tabRow.Name(L"Tab Row");
|
||||
_tabContent = Controls::Grid{};
|
||||
_tabContent.Name(L"Tab Content");
|
||||
|
||||
// Set up two columns in the tabs row - one for the tabs themselves, and
|
||||
// another for the settings button.
|
||||
auto tabsColDef = Controls::ColumnDefinition();
|
||||
auto newTabBtnColDef = Controls::ColumnDefinition();
|
||||
|
||||
newTabBtnColDef.Width(GridLengthHelper::Auto());
|
||||
|
||||
_tabRow.ColumnDefinitions().Append(tabsColDef);
|
||||
_tabRow.ColumnDefinitions().Append(newTabBtnColDef);
|
||||
|
||||
// Set up two rows - one for the tabs, the other for the tab content,
|
||||
// the terminal panes.
|
||||
auto tabBarRowDef = Controls::RowDefinition();
|
||||
tabBarRowDef.Height(GridLengthHelper::Auto());
|
||||
_root.RowDefinitions().Append(tabBarRowDef);
|
||||
_root.RowDefinitions().Append(Controls::RowDefinition{});
|
||||
|
||||
if (_settings->GlobalSettings().GetShowTabsInTitlebar() == false)
|
||||
{
|
||||
_root.Children().Append(_tabRow);
|
||||
Controls::Grid::SetRow(_tabRow, 0);
|
||||
}
|
||||
_root.Children().Append(_tabContent);
|
||||
Controls::Grid::SetRow(_tabContent, 1);
|
||||
Controls::Grid::SetColumn(_tabView, 0);
|
||||
|
||||
// Create the new tab button.
|
||||
_newTabButton = Controls::SplitButton{};
|
||||
Controls::SymbolIcon newTabIco{};
|
||||
newTabIco.Symbol(Controls::Symbol::Add);
|
||||
_newTabButton.Content(newTabIco);
|
||||
Controls::Grid::SetRow(_newTabButton, 0);
|
||||
Controls::Grid::SetColumn(_newTabButton, 1);
|
||||
_newTabButton.VerticalAlignment(VerticalAlignment::Stretch);
|
||||
_newTabButton.HorizontalAlignment(HorizontalAlignment::Left);
|
||||
|
||||
// When the new tab button is clicked, open the default profile
|
||||
_newTabButton.Click([this](auto&&, auto&&) {
|
||||
this->_OpenNewTab(std::nullopt);
|
||||
});
|
||||
|
||||
// Populate the new tab button's flyout with entries for each profile
|
||||
_CreateNewTabFlyout();
|
||||
|
||||
_tabRow.Children().Append(_tabView);
|
||||
_tabRow.Children().Append(_newTabButton);
|
||||
|
||||
_tabContent.VerticalAlignment(VerticalAlignment::Stretch);
|
||||
_tabContent.HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
|
||||
// Here, we're doing the equivalent of defining the _tabRow as the
|
||||
// following: <Grid Background="{ThemeResource
|
||||
// ApplicationPageBackgroundThemeBrush}"> We need to set the Background
|
||||
// to that ThemeResource, so it'll be colored appropriately regardless
|
||||
// of what theme the user has selected.
|
||||
// We're looking up the Style we've defined in App.xaml, and applying it
|
||||
// here. A ResourceDictionary is a Map<IInspectable, IInspectable>, so
|
||||
// you'll need to try_as to get the type we actually want.
|
||||
auto res = Resources();
|
||||
IInspectable key = winrt::box_value(L"BackgroundGridThemeStyle");
|
||||
if (res.HasKey(key))
|
||||
{
|
||||
IInspectable g = res.Lookup(key);
|
||||
winrt::Windows::UI::Xaml::Style style = g.try_as<winrt::Windows::UI::Xaml::Style>();
|
||||
_root.Style(style);
|
||||
_tabRow.Style(style);
|
||||
}
|
||||
|
||||
// Apply the UI theme from our settings to our UI elements
|
||||
_ApplyTheme(_settings->GlobalSettings().GetRequestedTheme());
|
||||
|
||||
_OpenNewTab(std::nullopt);
|
||||
|
||||
_tabContent.SizeChanged({ this, &App::_OnContentSizeChanged });
|
||||
_root.Loaded({ this, &App::_OnLoaded });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -146,10 +206,9 @@ namespace winrt::TerminalApp::implementation
|
||||
dialog.Content(contentElement);
|
||||
dialog.CloseButtonText(closeButtonText);
|
||||
|
||||
// IMPORTANT: This is necessary as documented in the ContentDialog MSDN docs.
|
||||
// Since we're hosting the dialog in a Xaml island, we need to connect it to the
|
||||
// xaml tree somehow.
|
||||
dialog.XamlRoot(_root.XamlRoot());
|
||||
// IMPORTANT: Add the dialog to the _root UIElement before you show it,
|
||||
// so it knows how to attach to the XAML content.
|
||||
_root.Children().Append(dialog);
|
||||
|
||||
// Display the dialog.
|
||||
Controls::ContentDialogResult result = co_await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup);
|
||||
@@ -179,74 +238,32 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Method Description:
|
||||
// - Show a dialog with "About" information. Displays the app's Display
|
||||
// Name, version, getting started link, documentation link, and release
|
||||
// Notes link.
|
||||
// Name, and the version.
|
||||
void App::_ShowAboutDialog()
|
||||
{
|
||||
auto resourceLoader = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView();
|
||||
const auto title = resourceLoader.GetString(L"AboutTitleText");
|
||||
const auto versionLabel = resourceLoader.GetString(L"VersionLabelText");
|
||||
const auto gettingStartedLabel = resourceLoader.GetString(L"GettingStartedLabelText");
|
||||
const auto documentationLabel = resourceLoader.GetString(L"DocumentationLabelText");
|
||||
const auto releaseNotesLabel = resourceLoader.GetString(L"ReleaseNotesLabelText");
|
||||
const auto gettingStartedUriValue = resourceLoader.GetString(L"GettingStartedUriValue");
|
||||
const auto documentationUriValue = resourceLoader.GetString(L"DocumentationUriValue");
|
||||
const auto releaseNotesUriValue = resourceLoader.GetString(L"ReleaseNotesUriValue");
|
||||
const auto package = winrt::Windows::ApplicationModel::Package::Current();
|
||||
const auto packageName = package.DisplayName();
|
||||
const auto version = package.Id().Version();
|
||||
Windows::UI::Xaml::Media::SolidColorBrush blueBrush{ Windows::UI::ColorHelper::FromArgb(255, 0, 115, 207) };
|
||||
winrt::Windows::UI::Xaml::Documents::Run about;
|
||||
winrt::Windows::UI::Xaml::Documents::Run gettingStarted;
|
||||
winrt::Windows::UI::Xaml::Documents::Run documentation;
|
||||
winrt::Windows::UI::Xaml::Documents::Run releaseNotes;
|
||||
winrt::Windows::UI::Xaml::Documents::Hyperlink gettingStartedLink;
|
||||
winrt::Windows::UI::Xaml::Documents::Hyperlink documentationLink;
|
||||
winrt::Windows::UI::Xaml::Documents::Hyperlink releaseNotesLink;
|
||||
std::wstringstream aboutTextStream;
|
||||
|
||||
gettingStarted.Text(gettingStartedLabel);
|
||||
documentation.Text(documentationLabel);
|
||||
releaseNotes.Text(releaseNotesLabel);
|
||||
|
||||
winrt::Windows::Foundation::Uri gettingStartedUri{ gettingStartedUriValue };
|
||||
winrt::Windows::Foundation::Uri documentationUri{ documentationUriValue };
|
||||
winrt::Windows::Foundation::Uri releaseNotesUri{ releaseNotesUriValue };
|
||||
|
||||
gettingStartedLink.NavigateUri(gettingStartedUri);
|
||||
documentationLink.NavigateUri(documentationUri);
|
||||
releaseNotesLink.NavigateUri(releaseNotesUri);
|
||||
|
||||
gettingStartedLink.Inlines().Append(gettingStarted);
|
||||
documentationLink.Inlines().Append(documentation);
|
||||
releaseNotesLink.Inlines().Append(releaseNotes);
|
||||
|
||||
// Format our about text. It will look like the following:
|
||||
// <Display Name>
|
||||
// Version: <Major>.<Minor>.<Build>.<Revision>
|
||||
// Getting Started
|
||||
// Documentation
|
||||
// Release Notes
|
||||
|
||||
aboutTextStream << packageName.c_str() << L"\n";
|
||||
|
||||
aboutTextStream << versionLabel.c_str() << L" ";
|
||||
aboutTextStream << version.Major << L"." << version.Minor << L"." << version.Build << L"." << version.Revision << L"\n";
|
||||
aboutTextStream << version.Major << L"." << version.Minor << L"." << version.Build << L"." << version.Revision;
|
||||
|
||||
winrt::hstring aboutText{ aboutTextStream.str() };
|
||||
about.Text(aboutText);
|
||||
|
||||
const auto buttonText = resourceLoader.GetString(L"Ok");
|
||||
|
||||
gettingStartedLink.Foreground(blueBrush);
|
||||
documentationLink.Foreground(blueBrush);
|
||||
releaseNotesLink.Foreground(blueBrush);
|
||||
|
||||
Controls::TextBlock aboutTextBlock;
|
||||
aboutTextBlock.Inlines().Append(about);
|
||||
aboutTextBlock.Inlines().Append(gettingStartedLink);
|
||||
aboutTextBlock.Inlines().Append(documentationLink);
|
||||
aboutTextBlock.Inlines().Append(releaseNotesLink);
|
||||
aboutTextBlock.Text(aboutText);
|
||||
aboutTextBlock.IsTextSelectionEnabled(true);
|
||||
|
||||
_ShowDialog(winrt::box_value(title), aboutTextBlock, buttonText);
|
||||
@@ -424,12 +441,7 @@ namespace winrt::TerminalApp::implementation
|
||||
co_await winrt::resume_background();
|
||||
|
||||
const auto settingsPath = CascadiaSettings::GetSettingsPath();
|
||||
|
||||
HINSTANCE res = ShellExecute(nullptr, nullptr, settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
|
||||
if (static_cast<int>(reinterpret_cast<uintptr_t>(res)) <= 32)
|
||||
{
|
||||
ShellExecute(nullptr, nullptr, L"notepad", settingsPath.c_str(), nullptr, SW_SHOW);
|
||||
}
|
||||
ShellExecute(nullptr, L"open", settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -451,19 +463,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void App::_FeedbackButtonOnClick(const IInspectable&,
|
||||
const RoutedEventArgs&)
|
||||
{
|
||||
const auto feedbackUriValue = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView().GetString(L"FeedbackUriValue");
|
||||
|
||||
winrt::Windows::System::Launcher::LaunchUriAsync({ feedbackUriValue });
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::Controls::Border App::GetDragBar() noexcept
|
||||
{
|
||||
if (_minMaxCloseControl)
|
||||
{
|
||||
return _minMaxCloseControl.DragBar();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
winrt::Windows::System::Launcher::LaunchUriAsync({ L"https://github.com/microsoft/Terminal/issues" });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -491,7 +491,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// They should all be hooked up here, regardless of whether or not
|
||||
// there's an actual keychord for them.
|
||||
bindings.NewTab([this]() { _OpenNewTab(std::nullopt); });
|
||||
bindings.DuplicateTab([this]() { _DuplicateTabViewItem(); });
|
||||
bindings.CloseTab([this]() { _CloseFocusedTab(); });
|
||||
bindings.NewTabWithProfile([this](const auto index) { _OpenNewTab({ index }); });
|
||||
bindings.ScrollUp([this]() { _Scroll(-1); });
|
||||
@@ -504,9 +503,6 @@ namespace winrt::TerminalApp::implementation
|
||||
bindings.ScrollDownPage([this]() { _ScrollPage(1); });
|
||||
bindings.SwitchToTab([this](const auto index) { _SelectTab({ index }); });
|
||||
bindings.OpenSettings([this]() { _OpenSettings(); });
|
||||
bindings.ResizePane([this](const auto direction) { _ResizePane(direction); });
|
||||
bindings.CopyText([this](const auto trimWhitespace) { _CopyText(trimWhitespace); });
|
||||
bindings.PasteText([this]() { _PasteText(); });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -676,7 +672,6 @@ namespace winrt::TerminalApp::implementation
|
||||
for (auto& tab : _tabs)
|
||||
{
|
||||
_UpdateTabIcon(tab);
|
||||
_UpdateTitle(tab);
|
||||
}
|
||||
|
||||
_root.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this]() {
|
||||
@@ -722,21 +717,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void App::_UpdateTitle(std::shared_ptr<Tab> tab)
|
||||
{
|
||||
auto newTabTitle = tab->GetFocusedTitle();
|
||||
const auto lastFocusedProfile = tab->GetFocusedProfile().value();
|
||||
const auto* const matchingProfile = _settings->FindProfile(lastFocusedProfile);
|
||||
|
||||
const auto tabTitle = matchingProfile->GetTabTitle();
|
||||
|
||||
// Checks if tab title has been set in the profile settings and
|
||||
// updates accordingly.
|
||||
|
||||
const auto newActualTitle = tabTitle.empty() ? newTabTitle : tabTitle;
|
||||
|
||||
tab->SetTabText(winrt::to_hstring(newActualTitle.data()));
|
||||
// TODO #608: If the settings don't want the terminal's text in the
|
||||
// tab, then display something else.
|
||||
tab->SetTabText(newTabTitle);
|
||||
if (_settings->GlobalSettings().GetShowTitleInTitlebar() &&
|
||||
tab->IsFocused())
|
||||
{
|
||||
_titleChangeHandlers(newActualTitle);
|
||||
_titleChangeHandlers(newTabTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,6 +736,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void App::_ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme)
|
||||
{
|
||||
_root.RequestedTheme(newTheme);
|
||||
_tabRow.RequestedTheme(newTheme);
|
||||
}
|
||||
|
||||
UIElement App::GetRoot() noexcept
|
||||
@@ -755,6 +744,11 @@ namespace winrt::TerminalApp::implementation
|
||||
return _root;
|
||||
}
|
||||
|
||||
UIElement App::GetTabs() noexcept
|
||||
{
|
||||
return _tabRow;
|
||||
}
|
||||
|
||||
void App::_SetFocusedTabIndex(int tabIndex)
|
||||
{
|
||||
// GH#1117: This is a workaround because _tabView.SelectedIndex(tabIndex)
|
||||
@@ -911,34 +905,22 @@ namespace winrt::TerminalApp::implementation
|
||||
// currently displayed, it will be shown.
|
||||
// Arguments:
|
||||
// - settings: the TerminalSettings object to use to create the TerminalControl with.
|
||||
void App::_CreateNewTabFromSettings(GUID profileGuid, TerminalSettings settings, std::optional<uint64_t> serverHandle)
|
||||
void App::_CreateNewTabFromSettings(GUID profileGuid, TerminalSettings settings)
|
||||
{
|
||||
// Initialize the new tab
|
||||
|
||||
TerminalConnection::ITerminalConnection connection = nullptr;
|
||||
// Create a Conhost connection based on the values in our settings object.
|
||||
if (!serverHandle)
|
||||
{
|
||||
connection = TerminalConnection::ConhostConnection(settings.Commandline(), settings.StartingDirectory(), 30, 80, winrt::guid());
|
||||
}
|
||||
else
|
||||
{
|
||||
connection = TerminalConnection::ConhostConnection(serverHandle.value(), 30, 80, winrt::guid());
|
||||
}
|
||||
|
||||
TermControl term{ settings, connection };
|
||||
TermControl term{ settings };
|
||||
|
||||
// Add the new tab to the list of our tabs.
|
||||
auto newTab = _tabs.emplace_back(std::make_shared<Tab>(profileGuid, term));
|
||||
|
||||
const auto* const profile = _settings->FindProfile(profileGuid);
|
||||
|
||||
// Hookup our event handlers to the new terminal
|
||||
_RegisterTerminalEvents(term, newTab);
|
||||
|
||||
auto tabViewItem = newTab->GetTabViewItem();
|
||||
_tabView.Items().Append(tabViewItem);
|
||||
|
||||
const auto* const profile = _settings->FindProfile(profileGuid);
|
||||
|
||||
// Set this profile's tab to the icon the user specified
|
||||
if (profile != nullptr && profile->HasIcon())
|
||||
{
|
||||
@@ -1022,20 +1004,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_tabs[focusedTabIndex]->Scroll(termHeight * delta);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempt to move a separator between panes, as to resize each child on
|
||||
// either size of the separator. See Pane::ResizePane for details.
|
||||
// - Moves a separator on the currently focused tab.
|
||||
// Arguments:
|
||||
// - direction: The direction to move the separator in.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void App::_ResizePane(const Direction& direction)
|
||||
{
|
||||
const auto focusedTabIndex = _GetFocusedTabIndex();
|
||||
_tabs[focusedTabIndex]->ResizePane(direction);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Copy text from the focused terminal to the Windows Clipboard
|
||||
// Arguments:
|
||||
@@ -1047,14 +1015,6 @@ namespace winrt::TerminalApp::implementation
|
||||
control.CopySelectionToClipboard(trimTrailingWhitespace);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Paste text from the Windows Clipboard to the focused terminal
|
||||
void App::_PasteText()
|
||||
{
|
||||
const auto control = _GetFocusedControl();
|
||||
control.PasteTextFromClipboard();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets focus to the tab to the right or left the currently selected tab.
|
||||
void App::_SelectNextTab(const bool bMoveRight)
|
||||
@@ -1166,33 +1126,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return { L"Windows Terminal" };
|
||||
}
|
||||
|
||||
void App::IncomingConnection(uint64_t serverHandle)
|
||||
{
|
||||
_root.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, serverHandle]() {
|
||||
// Getting Guid for default profile
|
||||
const auto globalSettings = _settings->GlobalSettings();
|
||||
auto profileGuid = globalSettings.GetDefaultProfile();
|
||||
TerminalSettings settings = _settings->MakeSettings(profileGuid);
|
||||
|
||||
_CreateNewTabFromSettings(profileGuid, settings, serverHandle);
|
||||
});
|
||||
}
|
||||
|
||||
void App::IncomingConnection(hstring cmdline, hstring workingDir)
|
||||
{
|
||||
_root.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, cmdline, workingDir]() {
|
||||
// Getting Guid for default profile
|
||||
const auto globalSettings = _settings->GlobalSettings();
|
||||
auto profileGuid = globalSettings.GetDefaultProfile();
|
||||
TerminalSettings settings = _settings->MakeSettings(profileGuid);
|
||||
|
||||
settings.Commandline(cmdline);
|
||||
settings.StartingDirectory(workingDir);
|
||||
|
||||
_CreateNewTabFromSettings(profileGuid, settings);
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Additional responses to clicking on a TabView's item. Currently, just remove tab with middle click
|
||||
// Arguments:
|
||||
@@ -1207,19 +1140,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Duplicates the current focused tab
|
||||
void App::_DuplicateTabViewItem()
|
||||
{
|
||||
const int& focusedTabIndex = _GetFocusedTabIndex();
|
||||
const auto& _tab = _tabs.at(focusedTabIndex);
|
||||
|
||||
const auto& profileGuid = _tab->GetFocusedProfile();
|
||||
const auto& settings = _settings->MakeSettings(profileGuid);
|
||||
|
||||
_CreateNewTabFromSettings(profileGuid.value(), settings);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Removes the tab (both TerminalControl and XAML)
|
||||
// Arguments:
|
||||
@@ -1336,11 +1256,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto realGuid = profileGuid ? profileGuid.value() :
|
||||
_settings->GlobalSettings().GetDefaultProfile();
|
||||
const auto controlSettings = _settings->MakeSettings(realGuid);
|
||||
|
||||
// Create a Conhost connection based on the values in our settings object.
|
||||
TerminalConnection::ITerminalConnection controlConnection = TerminalConnection::ConhostConnection(controlSettings.Commandline(), controlSettings.StartingDirectory(), 30, 80, winrt::guid());
|
||||
|
||||
TermControl newControl{ controlSettings, controlConnection };
|
||||
TermControl newControl{ controlSettings };
|
||||
|
||||
const int focusedTabIndex = _GetFocusedTabIndex();
|
||||
auto focusedTab = _tabs[focusedTabIndex];
|
||||
@@ -1352,23 +1268,6 @@ namespace winrt::TerminalApp::implementation
|
||||
focusedTab->AddVerticalSplit(realGuid, newControl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when our tab content size changes. This updates each tab with
|
||||
// the new size, so they have a chance to update each of their panes with
|
||||
// the new size.
|
||||
// Arguments:
|
||||
// - e: the SizeChangedEventArgs with the new size of the tab content area.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void App::_OnContentSizeChanged(const IInspectable& /*sender*/, Windows::UI::Xaml::SizeChangedEventArgs const& e)
|
||||
{
|
||||
const auto newSize = e.NewSize();
|
||||
for (auto& tab : _tabs)
|
||||
{
|
||||
tab->ResizeContent(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Place `copiedData` into the clipboard as text. Triggered when a
|
||||
// terminal control raises it's CopyToClipboard event.
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
#include "Tab.h"
|
||||
#include "CascadiaSettings.h"
|
||||
#include "App.g.h"
|
||||
#include "App.base.h"
|
||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
@@ -20,17 +18,18 @@
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct App : AppT2<App>
|
||||
// We dont use AppT as it does not provide access to protected constructors
|
||||
template<typename D, typename... I>
|
||||
using AppT_Override = App_base<D, I...>;
|
||||
|
||||
struct App : AppT_Override<App>
|
||||
{
|
||||
public:
|
||||
App();
|
||||
|
||||
Windows::UI::Xaml::UIElement GetRoot() noexcept;
|
||||
|
||||
// Gets the current dragglable area in the non client region of the top level window
|
||||
Windows::UI::Xaml::Controls::Border GetDragBar() noexcept;
|
||||
|
||||
void Create(uint64_t hParentWnd);
|
||||
Windows::UI::Xaml::UIElement GetTabs() noexcept;
|
||||
void Create();
|
||||
void LoadSettings();
|
||||
|
||||
Windows::Foundation::Point GetLaunchDimensions(uint32_t dpi);
|
||||
@@ -40,26 +39,24 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
hstring GetTitle();
|
||||
|
||||
void IncomingConnection(uint64_t serverHandle);
|
||||
void IncomingConnection(hstring cmdline, hstring workingDir);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
DECLARE_EVENT(TitleChanged, _titleChangeHandlers, winrt::Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
|
||||
DECLARE_EVENT(LastTabClosed, _lastTabClosedHandlers, winrt::TerminalApp::LastTabClosedEventArgs);
|
||||
|
||||
private:
|
||||
App(Windows::UI::Xaml::Markup::IXamlMetadataProvider const& parentProvider);
|
||||
|
||||
// If you add controls here, but forget to null them either here or in
|
||||
// the ctor, you're going to have a bad time. It'll mysteriously fail to
|
||||
// activate the app.
|
||||
// ALSO: If you add any UIElements as roots here, make sure they're
|
||||
// updated in _ApplyTheme. The two roots currently are _root and _tabRow
|
||||
// (which is a root when the tabs are in the titlebar.)
|
||||
Windows::UI::Xaml::Controls::Control _root{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Grid _root{ nullptr };
|
||||
Microsoft::UI::Xaml::Controls::TabView _tabView{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Grid _tabRow{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
|
||||
Windows::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
|
||||
winrt::TerminalApp::MinMaxCloseControl _minMaxCloseControl{ nullptr };
|
||||
|
||||
std::vector<std::shared_ptr<Tab>> _tabs;
|
||||
|
||||
@@ -74,7 +71,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
std::atomic<bool> _settingsReloadQueued{ false };
|
||||
|
||||
void _Create(uint64_t parentHWnd);
|
||||
void _Create();
|
||||
void _CreateNewTabFlyout();
|
||||
|
||||
fire_and_forget _ShowDialog(const winrt::Windows::Foundation::IInspectable& titleElement,
|
||||
@@ -103,10 +100,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _RegisterTerminalEvents(Microsoft::Terminal::TerminalControl::TermControl term, std::shared_ptr<Tab> hostingTab);
|
||||
|
||||
void _CreateNewTabFromSettings(GUID profileGuid, winrt::Microsoft::Terminal::Settings::TerminalSettings settings, std::optional<uint64_t> serverHandle = std::nullopt);
|
||||
void _CreateNewTabFromSettings(GUID profileGuid, winrt::Microsoft::Terminal::Settings::TerminalSettings settings);
|
||||
|
||||
void _OpenNewTab(std::optional<int> profileIndex);
|
||||
void _DuplicateTabViewItem();
|
||||
void _CloseFocusedTab();
|
||||
void _SelectNextTab(const bool bMoveRight);
|
||||
void _SelectTab(const int tabIndex);
|
||||
@@ -116,22 +112,18 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _Scroll(int delta);
|
||||
void _CopyText(const bool trimTrailingWhitespace);
|
||||
void _PasteText();
|
||||
void _SplitVertical(const std::optional<GUID>& profileGuid);
|
||||
void _SplitHorizontal(const std::optional<GUID>& profileGuid);
|
||||
void _SplitPane(const Pane::SplitState splitType, const std::optional<GUID>& profileGuid);
|
||||
|
||||
// Todo: add more event implementations here
|
||||
// MSFT:20641986: Add keybindings for New Window
|
||||
void _ScrollPage(int delta);
|
||||
void _ResizePane(const Direction& direction);
|
||||
|
||||
void _OnLoaded(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||
void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
|
||||
void _OnTabClosing(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabClosingEventArgs& eventArgs);
|
||||
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
|
||||
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
|
||||
void _OnContentSizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
|
||||
|
||||
void _RemoveTabViewItem(const IInspectable& tabViewItem);
|
||||
|
||||
|
||||
@@ -5,23 +5,21 @@ namespace TerminalApp
|
||||
{
|
||||
delegate void LastTabClosedEventArgs();
|
||||
[default_interface]
|
||||
runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
|
||||
runtimeclass App : Microsoft.UI.Xaml.Markup.XamlApplication
|
||||
{
|
||||
App();
|
||||
|
||||
void Initialize();
|
||||
|
||||
// For your own sanity, it's better to do setup outside the ctor.
|
||||
// If you do any setup in the ctor that ends up throwing an exception,
|
||||
// then it might look like TermApp just failed to activate, which will
|
||||
// cause you to chase down the rabbit hole of "why is TermApp not
|
||||
// registered?" when it definitely is.
|
||||
void Create(UInt64 hParentWnd);
|
||||
void Create();
|
||||
|
||||
void LoadSettings();
|
||||
|
||||
Windows.UI.Xaml.UIElement GetRoot();
|
||||
Windows.UI.Xaml.Controls.Border GetDragBar{ get; };
|
||||
Windows.UI.Xaml.UIElement GetTabs();
|
||||
|
||||
Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi);
|
||||
Boolean GetShowTabsInTitlebar();
|
||||
@@ -31,7 +29,10 @@ namespace TerminalApp
|
||||
|
||||
String GetTitle();
|
||||
|
||||
void IncomingConnection(UInt64 serverHandle);
|
||||
void IncomingConnection(String cmdline, String workingDir);
|
||||
// IXamlMetadataProvider, Xaml.Application:
|
||||
// Application's composing initializer will register the composing class
|
||||
// as the toplevel "active" Xaml application. This Application (through IXamlMetadataProvider)
|
||||
// will be queried for all unknown types during all Xaml and XBF (Xaml Binary Format) parse
|
||||
// operations.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<Toolkit:XamlApplication
|
||||
<MSMarkup:XamlApplication
|
||||
x:Class="TerminalApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost"
|
||||
xmlns:MSMarkup="using:Microsoft.UI.Xaml.Markup"
|
||||
xmlns:TA="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<!-- If you want to prove this works, then add `RequestedTheme="Light"` to
|
||||
the properties on the XamlApplication -->
|
||||
<Toolkit:XamlApplication.Resources>
|
||||
<MSMarkup:XamlApplication.Resources>
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
@@ -60,5 +60,5 @@ the MIT License. See LICENSE in the project root for license information. -->
|
||||
</ResourceDictionary>
|
||||
|
||||
|
||||
</Toolkit:XamlApplication.Resources>
|
||||
</Toolkit:XamlApplication>
|
||||
</MSMarkup:XamlApplication.Resources>
|
||||
</MSMarkup:XamlApplication>
|
||||
|
||||
@@ -47,10 +47,7 @@ namespace winrt::TerminalApp::implementation
|
||||
switch (action)
|
||||
{
|
||||
case ShortcutAction::CopyText:
|
||||
_CopyTextHandlers(true);
|
||||
return true;
|
||||
case ShortcutAction::CopyTextWithoutNewlines:
|
||||
_CopyTextHandlers(false);
|
||||
_CopyTextHandlers();
|
||||
return true;
|
||||
case ShortcutAction::PasteText:
|
||||
_PasteTextHandlers();
|
||||
@@ -58,9 +55,6 @@ namespace winrt::TerminalApp::implementation
|
||||
case ShortcutAction::NewTab:
|
||||
_NewTabHandlers();
|
||||
return true;
|
||||
case ShortcutAction::DuplicateTab:
|
||||
_DuplicateTabHandlers();
|
||||
return true;
|
||||
case ShortcutAction::OpenSettings:
|
||||
_OpenSettingsHandlers();
|
||||
return true;
|
||||
@@ -157,18 +151,6 @@ namespace winrt::TerminalApp::implementation
|
||||
case ShortcutAction::SwitchToTab8:
|
||||
_SwitchToTabHandlers(8);
|
||||
return true;
|
||||
case ShortcutAction::ResizePaneLeft:
|
||||
_ResizePaneHandlers(Direction::Left);
|
||||
return true;
|
||||
case ShortcutAction::ResizePaneRight:
|
||||
_ResizePaneHandlers(Direction::Right);
|
||||
return true;
|
||||
case ShortcutAction::ResizePaneUp:
|
||||
_ResizePaneHandlers(Direction::Up);
|
||||
return true;
|
||||
case ShortcutAction::ResizePaneDown:
|
||||
_ResizePaneHandlers(Direction::Down);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
@@ -233,7 +215,6 @@ namespace winrt::TerminalApp::implementation
|
||||
DEFINE_EVENT(AppKeyBindings, CopyText, _CopyTextHandlers, TerminalApp::CopyTextEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, PasteText, _PasteTextHandlers, TerminalApp::PasteTextEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, NewTab, _NewTabHandlers, TerminalApp::NewTabEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, DuplicateTab, _DuplicateTabHandlers, TerminalApp::DuplicateTabEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, NewTabWithProfile, _NewTabWithProfileHandlers, TerminalApp::NewTabWithProfileEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs);
|
||||
@@ -241,7 +222,7 @@ namespace winrt::TerminalApp::implementation
|
||||
DEFINE_EVENT(AppKeyBindings, SwitchToTab, _SwitchToTabHandlers, TerminalApp::SwitchToTabEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, NextTab, _NextTabHandlers, TerminalApp::NextTabEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, PrevTab, _PrevTabHandlers, TerminalApp::PrevTabEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, SplitVertical, _SplitVerticalHandlers, TerminalApp::SplitVerticalEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, SplitVertical, _SplitVerticalHandlers, TerminalApp::SplitVerticalEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, SplitHorizontal, _SplitHorizontalHandlers, TerminalApp::SplitHorizontalEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, IncreaseFontSize, _IncreaseFontSizeHandlers, TerminalApp::IncreaseFontSizeEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, DecreaseFontSize, _DecreaseFontSizeHandlers, TerminalApp::DecreaseFontSizeEventArgs);
|
||||
@@ -250,6 +231,5 @@ namespace winrt::TerminalApp::implementation
|
||||
DEFINE_EVENT(AppKeyBindings, ScrollUpPage, _ScrollUpPageHandlers, TerminalApp::ScrollUpPageEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, ScrollDownPage, _ScrollDownPageHandlers, TerminalApp::ScrollDownPageEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
|
||||
DEFINE_EVENT(AppKeyBindings, ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace winrt::TerminalApp::implementation
|
||||
DECLARE_EVENT(CopyText, _CopyTextHandlers, TerminalApp::CopyTextEventArgs);
|
||||
DECLARE_EVENT(PasteText, _PasteTextHandlers, TerminalApp::PasteTextEventArgs);
|
||||
DECLARE_EVENT(NewTab, _NewTabHandlers, TerminalApp::NewTabEventArgs);
|
||||
DECLARE_EVENT(DuplicateTab, _DuplicateTabHandlers, TerminalApp::DuplicateTabEventArgs);
|
||||
DECLARE_EVENT(NewTabWithProfile, _NewTabWithProfileHandlers, TerminalApp::NewTabWithProfileEventArgs);
|
||||
DECLARE_EVENT(NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs);
|
||||
DECLARE_EVENT(CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs);
|
||||
@@ -60,7 +59,6 @@ namespace winrt::TerminalApp::implementation
|
||||
DECLARE_EVENT(ScrollUpPage, _ScrollUpPageHandlers, TerminalApp::ScrollUpPageEventArgs);
|
||||
DECLARE_EVENT(ScrollDownPage, _ScrollDownPageHandlers, TerminalApp::ScrollDownPageEventArgs);
|
||||
DECLARE_EVENT(OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
|
||||
DECLARE_EVENT(ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
|
||||
@@ -3,21 +3,11 @@
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
enum Direction
|
||||
{
|
||||
Left = 0,
|
||||
Right,
|
||||
Up,
|
||||
Down
|
||||
};
|
||||
|
||||
enum ShortcutAction
|
||||
{
|
||||
CopyText = 0,
|
||||
CopyTextWithoutNewlines,
|
||||
PasteText,
|
||||
NewTab,
|
||||
DuplicateTab,
|
||||
NewTabProfile0,
|
||||
NewTabProfile1,
|
||||
NewTabProfile2,
|
||||
@@ -49,17 +39,12 @@ namespace TerminalApp
|
||||
ScrollDown,
|
||||
ScrollUpPage,
|
||||
ScrollDownPage,
|
||||
ResizePaneLeft,
|
||||
ResizePaneRight,
|
||||
ResizePaneUp,
|
||||
ResizePaneDown,
|
||||
OpenSettings
|
||||
};
|
||||
|
||||
delegate void CopyTextEventArgs(Boolean trimWhitespace);
|
||||
delegate void CopyTextEventArgs();
|
||||
delegate void PasteTextEventArgs();
|
||||
delegate void NewTabEventArgs();
|
||||
delegate void DuplicateTabEventArgs();
|
||||
delegate void NewTabWithProfileEventArgs(Int32 profileIndex);
|
||||
delegate void NewWindowEventArgs();
|
||||
delegate void CloseWindowEventArgs();
|
||||
@@ -76,7 +61,6 @@ namespace TerminalApp
|
||||
delegate void ScrollUpPageEventArgs();
|
||||
delegate void ScrollDownPageEventArgs();
|
||||
delegate void OpenSettingsEventArgs();
|
||||
delegate void ResizePaneEventArgs(Direction direction);
|
||||
|
||||
[default_interface]
|
||||
runtimeclass AppKeyBindings : Microsoft.Terminal.Settings.IKeyBindings
|
||||
@@ -89,7 +73,6 @@ namespace TerminalApp
|
||||
event CopyTextEventArgs CopyText;
|
||||
event PasteTextEventArgs PasteText;
|
||||
event NewTabEventArgs NewTab;
|
||||
event DuplicateTabEventArgs DuplicateTab;
|
||||
event NewTabWithProfileEventArgs NewTabWithProfile;
|
||||
event NewWindowEventArgs NewWindow;
|
||||
event CloseWindowEventArgs CloseWindow;
|
||||
@@ -106,6 +89,5 @@ namespace TerminalApp
|
||||
event ScrollUpPageEventArgs ScrollUpPage;
|
||||
event ScrollDownPageEventArgs ScrollDownPage;
|
||||
event OpenSettingsEventArgs OpenSettings;
|
||||
event ResizePaneEventArgs ResizePane;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@ static constexpr std::string_view KeysKey{ "keys" };
|
||||
static constexpr std::string_view CommandKey{ "command" };
|
||||
|
||||
static constexpr std::string_view CopyTextKey{ "copy" };
|
||||
static constexpr std::string_view CopyTextWithoutNewlinesKey{ "copyTextWithoutNewlines" };
|
||||
static constexpr std::string_view PasteTextKey{ "paste" };
|
||||
static constexpr std::string_view NewTabKey{ "newTab" };
|
||||
static constexpr std::string_view DuplicateTabKey{ "duplicateTab" };
|
||||
static constexpr std::string_view NewTabWithProfile0Key{ "newTabProfile0" };
|
||||
static constexpr std::string_view NewTabWithProfile1Key{ "newTabProfile1" };
|
||||
static constexpr std::string_view NewTabWithProfile2Key{ "newTabProfile2" };
|
||||
@@ -51,10 +49,6 @@ static constexpr std::string_view SwitchToTab8Key{ "switchToTab8" };
|
||||
static constexpr std::string_view OpenSettingsKey{ "openSettings" };
|
||||
static constexpr std::string_view SplitHorizontalKey{ "splitHorizontal" };
|
||||
static constexpr std::string_view SplitVerticalKey{ "splitVertical" };
|
||||
static constexpr std::string_view ResizePaneLeftKey{ "resizePaneLeft" };
|
||||
static constexpr std::string_view ResizePaneRightKey{ "resizePaneRight" };
|
||||
static constexpr std::string_view ResizePaneUpKey{ "resizePaneUp" };
|
||||
static constexpr std::string_view ResizePaneDownKey{ "resizePaneDown" };
|
||||
|
||||
// Specifically use a map here over an unordered_map. We want to be able to
|
||||
// iterate over these entries in-order when we're serializing the keybindings.
|
||||
@@ -66,10 +60,8 @@ static constexpr std::string_view ResizePaneDownKey{ "resizePaneDown" };
|
||||
// about here.
|
||||
static const std::map<std::string_view, ShortcutAction, std::less<>> commandNames{
|
||||
{ CopyTextKey, ShortcutAction::CopyText },
|
||||
{ CopyTextWithoutNewlinesKey, ShortcutAction::CopyTextWithoutNewlines },
|
||||
{ PasteTextKey, ShortcutAction::PasteText },
|
||||
{ NewTabKey, ShortcutAction::NewTab },
|
||||
{ DuplicateTabKey, ShortcutAction::DuplicateTab },
|
||||
{ NewTabWithProfile0Key, ShortcutAction::NewTabProfile0 },
|
||||
{ NewTabWithProfile1Key, ShortcutAction::NewTabProfile1 },
|
||||
{ NewTabWithProfile2Key, ShortcutAction::NewTabProfile2 },
|
||||
@@ -101,10 +93,6 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
|
||||
{ SwitchToTab8Key, ShortcutAction::SwitchToTab8 },
|
||||
{ SplitHorizontalKey, ShortcutAction::SplitHorizontal },
|
||||
{ SplitVerticalKey, ShortcutAction::SplitVertical },
|
||||
{ ResizePaneLeftKey, ShortcutAction::ResizePaneLeft },
|
||||
{ ResizePaneRightKey, ShortcutAction::ResizePaneRight },
|
||||
{ ResizePaneUpKey, ShortcutAction::ResizePaneUp },
|
||||
{ ResizePaneDownKey, ShortcutAction::ResizePaneDown },
|
||||
{ OpenSettingsKey, ShortcutAction::OpenSettings },
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Module Name:
|
||||
// - AppKeyBindingsSerialization.h
|
||||
// - Profile.hpp
|
||||
//
|
||||
// Abstract:
|
||||
// - A couple helper functions for serializing/deserializing an AppKeyBindings
|
||||
|
||||
@@ -49,35 +49,6 @@ ColorScheme _CreateCampbellScheme()
|
||||
|
||||
// clang-format off
|
||||
|
||||
ColorScheme _CreateVintageScheme()
|
||||
{
|
||||
// as per https://github.com/microsoft/terminal/issues/1781
|
||||
ColorScheme vintageScheme { L"Vintage",
|
||||
RGB(192, 192, 192),
|
||||
RGB( 0, 0, 0) };
|
||||
auto& vintageTable = vintageScheme.GetTable();
|
||||
auto vintageSpan = gsl::span<COLORREF>(&vintageTable[0], gsl::narrow<ptrdiff_t>(COLOR_TABLE_SIZE));
|
||||
vintageTable[0] = RGB( 0, 0, 0); // black
|
||||
vintageTable[1] = RGB(128, 0, 0); // dark red
|
||||
vintageTable[2] = RGB( 0, 128, 0); // dark green
|
||||
vintageTable[3] = RGB(128, 128, 0); // dark yellow
|
||||
vintageTable[4] = RGB( 0, 0, 128); // dark blue
|
||||
vintageTable[5] = RGB(128, 0, 128); // dark magenta
|
||||
vintageTable[6] = RGB( 0, 128, 128); // dark cyan
|
||||
vintageTable[7] = RGB(192, 192, 192); // gray
|
||||
vintageTable[8] = RGB(128, 128, 128); // dark gray
|
||||
vintageTable[9] = RGB(255, 0, 0); // red
|
||||
vintageTable[10] = RGB( 0, 255, 0); // green
|
||||
vintageTable[11] = RGB(255, 255, 0); // yellow
|
||||
vintageTable[12] = RGB( 0, 0, 255); // blue
|
||||
vintageTable[13] = RGB(255, 0, 255); // magenta
|
||||
vintageTable[14] = RGB( 0, 255, 255); // cyan
|
||||
vintageTable[15] = RGB(255, 255, 255); // white
|
||||
Utils::SetColorTableAlpha(vintageSpan, 0xff);
|
||||
|
||||
return vintageScheme;
|
||||
}
|
||||
|
||||
ColorScheme _CreateOneHalfDarkScheme()
|
||||
{
|
||||
// First 8 dark colors per: https://github.com/sonph/onehalf/blob/master/putty/onehalf-dark.reg
|
||||
@@ -208,7 +179,6 @@ ColorScheme _CreateSolarizedLightScheme()
|
||||
void CascadiaSettings::_CreateDefaultSchemes()
|
||||
{
|
||||
_globals.GetColorSchemes().emplace_back(_CreateCampbellScheme());
|
||||
_globals.GetColorSchemes().emplace_back(_CreateVintageScheme());
|
||||
_globals.GetColorSchemes().emplace_back(_CreateOneHalfDarkScheme());
|
||||
_globals.GetColorSchemes().emplace_back(_CreateOneHalfLightScheme());
|
||||
_globals.GetColorSchemes().emplace_back(_CreateSolarizedDarkScheme());
|
||||
@@ -283,22 +253,10 @@ void CascadiaSettings::_CreateDefaultKeybindings()
|
||||
keyBindings.SetKeyBinding(ShortcutAction::NewTab,
|
||||
KeyChord{ KeyModifiers::Ctrl,
|
||||
static_cast<int>('T') });
|
||||
keyBindings.SetKeyBinding(ShortcutAction::DuplicateTab,
|
||||
KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift,
|
||||
static_cast<int>('D') });
|
||||
|
||||
keyBindings.SetKeyBinding(ShortcutAction::CloseTab,
|
||||
KeyChord{ KeyModifiers::Ctrl,
|
||||
static_cast<int>('W') });
|
||||
|
||||
keyBindings.SetKeyBinding(ShortcutAction::CopyText,
|
||||
KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift,
|
||||
static_cast<int>('C') });
|
||||
|
||||
keyBindings.SetKeyBinding(ShortcutAction::PasteText,
|
||||
KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift,
|
||||
static_cast<int>('V') });
|
||||
|
||||
keyBindings.SetKeyBinding(ShortcutAction::OpenSettings,
|
||||
KeyChord{ KeyModifiers::Ctrl,
|
||||
VK_OEM_COMMA });
|
||||
|
||||
@@ -10,6 +10,8 @@ using namespace TerminalApp;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
static constexpr std::string_view TableKey{ "colors" };
|
||||
|
||||
@@ -17,6 +17,7 @@ Author(s):
|
||||
#pragma once
|
||||
#include <winrt/Microsoft.Terminal.Settings.h>
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
#include <winrt/TerminalApp.h>
|
||||
#include "../../inc/conattrs.hpp"
|
||||
|
||||
namespace TerminalApp
|
||||
|
||||
@@ -23,7 +23,6 @@ static constexpr std::string_view InitialColsKey{ "initialCols" };
|
||||
static constexpr std::string_view ShowTitleInTitlebarKey{ "showTerminalTitleInTitlebar" };
|
||||
static constexpr std::string_view RequestedThemeKey{ "requestedTheme" };
|
||||
static constexpr std::string_view ShowTabsInTitlebarKey{ "showTabsInTitlebar" };
|
||||
static constexpr std::string_view WordDelimitersKey{ "wordDelimiters" };
|
||||
|
||||
static constexpr std::wstring_view LightThemeValue{ L"light" };
|
||||
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
|
||||
@@ -38,8 +37,7 @@ GlobalAppSettings::GlobalAppSettings() :
|
||||
_initialCols{ DEFAULT_COLS },
|
||||
_showTitleInTitlebar{ true },
|
||||
_showTabsInTitlebar{ true },
|
||||
_requestedTheme{ ElementTheme::Default },
|
||||
_wordDelimiters{ DEFAULT_WORD_DELIMITERS }
|
||||
_requestedTheme{ ElementTheme::Default }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -107,16 +105,6 @@ void GlobalAppSettings::SetRequestedTheme(const ElementTheme requestedTheme) noe
|
||||
_requestedTheme = requestedTheme;
|
||||
}
|
||||
|
||||
std::wstring GlobalAppSettings::GetWordDelimiters() const noexcept
|
||||
{
|
||||
return _wordDelimiters;
|
||||
}
|
||||
|
||||
void GlobalAppSettings::SetWordDelimiters(const std::wstring wordDelimiters) noexcept
|
||||
{
|
||||
_wordDelimiters = wordDelimiters;
|
||||
}
|
||||
|
||||
#pragma region ExperimentalSettings
|
||||
bool GlobalAppSettings::GetShowTabsInTitlebar() const noexcept
|
||||
{
|
||||
@@ -140,7 +128,6 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce
|
||||
settings.KeyBindings(GetKeybindings());
|
||||
settings.InitialRows(_initialRows);
|
||||
settings.InitialCols(_initialCols);
|
||||
settings.WordDelimiters(_wordDelimiters);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -159,7 +146,6 @@ Json::Value GlobalAppSettings::ToJson() const
|
||||
jsonObject[JsonKey(AlwaysShowTabsKey)] = _alwaysShowTabs;
|
||||
jsonObject[JsonKey(ShowTitleInTitlebarKey)] = _showTitleInTitlebar;
|
||||
jsonObject[JsonKey(ShowTabsInTitlebarKey)] = _showTabsInTitlebar;
|
||||
jsonObject[JsonKey(WordDelimitersKey)] = winrt::to_string(_wordDelimiters);
|
||||
jsonObject[JsonKey(RequestedThemeKey)] = winrt::to_string(_SerializeTheme(_requestedTheme));
|
||||
jsonObject[JsonKey(KeybindingsKey)] = AppKeyBindingsSerialization::ToJson(_keybindings);
|
||||
|
||||
@@ -205,11 +191,6 @@ GlobalAppSettings GlobalAppSettings::FromJson(const Json::Value& json)
|
||||
result._showTabsInTitlebar = showTabsInTitlebar.asBool();
|
||||
}
|
||||
|
||||
if (auto wordDelimiters{ json[JsonKey(WordDelimitersKey)] })
|
||||
{
|
||||
result._wordDelimiters = GetWstringFromJson(wordDelimiters);
|
||||
}
|
||||
|
||||
if (auto requestedTheme{ json[JsonKey(RequestedThemeKey)] })
|
||||
{
|
||||
result._requestedTheme = _ParseTheme(GetWstringFromJson(requestedTheme));
|
||||
|
||||
@@ -47,9 +47,6 @@ public:
|
||||
bool GetShowTabsInTitlebar() const noexcept;
|
||||
void SetShowTabsInTitlebar(const bool showTabsInTitlebar) noexcept;
|
||||
|
||||
std::wstring GetWordDelimiters() const noexcept;
|
||||
void SetWordDelimiters(const std::wstring wordDelimiters) noexcept;
|
||||
|
||||
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme() const noexcept;
|
||||
|
||||
Json::Value ToJson() const;
|
||||
@@ -71,7 +68,6 @@ private:
|
||||
bool _showTitleInTitlebar;
|
||||
|
||||
bool _showTabsInTitlebar;
|
||||
std::wstring _wordDelimiters;
|
||||
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
|
||||
|
||||
static winrt::Windows::UI::Xaml::ElementTheme _ParseTheme(const std::wstring& themeString) noexcept;
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
//
|
||||
// MinMaxCloseControl.xaml.cpp
|
||||
// Implementation of the MinMaxCloseControl class
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "MinMaxCloseControl.h"
|
||||
|
||||
#include "MinMaxCloseControl.g.cpp"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
MinMaxCloseControl::MinMaxCloseControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
uint64_t MinMaxCloseControl::ParentWindowHandle() const
|
||||
{
|
||||
return reinterpret_cast<uint64_t>(_window);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::ParentWindowHandle(uint64_t handle)
|
||||
{
|
||||
_window = reinterpret_cast<HWND>(handle);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::_OnMaximize(byte flag)
|
||||
{
|
||||
if (_window)
|
||||
{
|
||||
POINT point1 = {};
|
||||
::GetCursorPos(&point1);
|
||||
const LPARAM lParam = MAKELPARAM(point1.x, point1.y);
|
||||
WINDOWPLACEMENT placement = { sizeof(placement) };
|
||||
::GetWindowPlacement(_window, &placement);
|
||||
if (placement.showCmd == SW_SHOWNORMAL)
|
||||
{
|
||||
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateMaximized", false);
|
||||
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
|
||||
}
|
||||
else if (placement.showCmd == SW_SHOWMAXIMIZED)
|
||||
{
|
||||
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateNormal", false);
|
||||
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
|
||||
{
|
||||
_OnMaximize(HTMAXBUTTON);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e)
|
||||
{
|
||||
_OnMaximize(HTCAPTION);
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
|
||||
{
|
||||
if (_window)
|
||||
{
|
||||
::PostMessage(_window, WM_SYSCOMMAND, SC_MINIMIZE | HTMINBUTTON, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MinMaxCloseControl::Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
//
|
||||
// Declaration of the MainUserControl class.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Windows.UI.Xaml.h"
|
||||
#include "winrt/Windows.UI.Xaml.Markup.h"
|
||||
#include "winrt/Windows.UI.Xaml.Interop.h"
|
||||
#include "MinMaxCloseControl.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct MinMaxCloseControl : MinMaxCloseControlT<MinMaxCloseControl>
|
||||
{
|
||||
MinMaxCloseControl();
|
||||
|
||||
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
|
||||
void DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e);
|
||||
|
||||
uint64_t ParentWindowHandle() const;
|
||||
void ParentWindowHandle(uint64_t handle);
|
||||
|
||||
private:
|
||||
void _OnMaximize(byte flag);
|
||||
HWND _window{ nullptr }; // non-owning handle; should not be freed in the dtor.
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
struct MinMaxCloseControl : MinMaxCloseControlT<MinMaxCloseControl, implementation::MinMaxCloseControl>
|
||||
{
|
||||
};
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass MinMaxCloseControl : Windows.UI.Xaml.Controls.StackPanel
|
||||
{
|
||||
MinMaxCloseControl();
|
||||
|
||||
Windows.UI.Xaml.Controls.Grid Content{ get; };
|
||||
Windows.UI.Xaml.Controls.Border DragBar{ get; };
|
||||
|
||||
UInt64 ParentWindowHandle;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
<StackPanel
|
||||
x:Class="TerminalApp.MinMaxCloseControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource SystemChromeLowColor}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Horizontal"
|
||||
d:DesignHeight="36"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<StackPanel.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="Red"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="Black"/>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="Red"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="Black"/>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<x:Double x:Key="CaptionButtonStrokeWidth">3.0</x:Double>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackground" Color="{ThemeResource SystemColorButtonFaceColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPressed" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStroke" Color="{ThemeResource SystemColorButtonTextColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePointerOver" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CaptionButtonStrokePressed" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="{ThemeResource SystemColorHighlightColor}"/>
|
||||
<SolidColorBrush x:Key="CloseButtonStrokePressed" Color="{ThemeResource SystemColorHighlightTextColor}"/>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<x:String x:Key="CaptionButtonPath"></x:String>
|
||||
<x:String x:Key="CaptionButtonPathWindowMaximized"></x:String>
|
||||
|
||||
<Style x:Key="CaptionButton" TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Background" Value="{ThemeResource CaptionButtonBackground}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="ButtonBaseElement"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
|
||||
<VisualState x:Name="PointerOver">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackgroundPointerOver}" />
|
||||
<Setter Target="Path.Stroke" Value="{ThemeResource CaptionButtonStrokePointerOver}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Pressed">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ButtonBaseElement.Background" Value="{ThemeResource CaptionButtonBackgroundPressed}" />
|
||||
<Setter Target="Path.Stroke" Value="{ThemeResource CaptionButtonStrokePressed}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
|
||||
<VisualStateGroup x:Name="MinMaxStates">
|
||||
<VisualState x:Name="WindowStateNormal" />
|
||||
|
||||
<VisualState x:Name="WindowStateMaximized">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Path.Data" Value="{ThemeResource CaptionButtonPathWindowMaximized}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Path
|
||||
x:Name="Path"
|
||||
StrokeThickness="{ThemeResource CaptionButtonStrokeWidth}"
|
||||
Stroke="{ThemeResource CaptionButtonStroke}"
|
||||
Data="{ThemeResource CaptionButtonPath}"
|
||||
Stretch="Fill"
|
||||
UseLayoutRounding="True"
|
||||
Width="10"
|
||||
Height="10"
|
||||
StrokeEndLineCap="Square"
|
||||
StrokeStartLineCap="Square" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<Grid x:Name="Content"></Grid>
|
||||
<Border Height="36.0"
|
||||
MinWidth="160.0"
|
||||
x:Name="DragBar"
|
||||
Background="{ThemeResource SystemChromeLowColor}"
|
||||
DoubleTapped="DragBar_DoubleTapped"/>
|
||||
<Button Height="36.0" Width="45.0" x:Name="Minimize" Style="{StaticResource CaptionButton}" Click="Minimize_Click"
|
||||
AutomationProperties.Name="Minimize">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 H 10</x:String>
|
||||
</ResourceDictionary>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
<Button Height="36.0" Width="45.0" x:Name="Maximize" Style="{StaticResource CaptionButton}" Click="Maximize_Click"
|
||||
AutomationProperties.Name="Maximize">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 H 10 V 10 H 0 V 0</x:String>
|
||||
<x:String x:Key="CaptionButtonPathWindowMaximized">M 0 2 h 8 v 8 h -8 v -8 M 2 2 v -2 h 8 v 8 h -2</x:String>
|
||||
</ResourceDictionary>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
<Button Height="36.0" Width="45.0" x:Name="Close" Style="{StaticResource CaptionButton}" Click="Close_Click"
|
||||
AutomationProperties.Name="Close">
|
||||
<Button.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="CloseButtonBackgroundPointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="CloseButtonBackgroundPressed"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="CloseButtonStrokePointerOver"/>
|
||||
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="CloseButtonStrokePressed"/>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<x:String x:Key="CaptionButtonPath">M 0 0 L 10 10 M 10 0 L 0 10</x:String>
|
||||
</ResourceDictionary>
|
||||
</Button.Resources>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
@@ -4,15 +4,12 @@
|
||||
#include "pch.h"
|
||||
#include "Pane.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalControl;
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
static const int PaneSeparatorSize = 4;
|
||||
static const float Half = 0.50f;
|
||||
|
||||
Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) :
|
||||
_control{ control },
|
||||
@@ -39,154 +36,6 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the size of this pane. Resizes each of our columns so they have the
|
||||
// same relative sizes, given the newSize.
|
||||
// - Because we're just manually setting the row/column sizes in pixels, we have
|
||||
// to be told our new size, we can't just use our own OnSized event, because
|
||||
// that _won't fire when we get smaller_.
|
||||
// Arguments:
|
||||
// - newSize: the amount of space that this pane has to fill now.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Pane::ResizeContent(const Size& newSize)
|
||||
{
|
||||
const auto width = newSize.Width;
|
||||
const auto height = newSize.Height;
|
||||
|
||||
_CreateRowColDefinitions(newSize);
|
||||
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
const auto paneSizes = _GetPaneSizes(width);
|
||||
|
||||
const Size firstSize{ paneSizes.first, height };
|
||||
const Size secondSize{ paneSizes.second, height };
|
||||
_firstChild->ResizeContent(firstSize);
|
||||
_secondChild->ResizeContent(secondSize);
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
const auto paneSizes = _GetPaneSizes(height);
|
||||
|
||||
const Size firstSize{ width, paneSizes.first };
|
||||
const Size secondSize{ width, paneSizes.second };
|
||||
_firstChild->ResizeContent(firstSize);
|
||||
_secondChild->ResizeContent(secondSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Adjust our child percentages to increase the size of one of our children
|
||||
// and decrease the size of the other.
|
||||
// - Adjusts the separation amount by 5%
|
||||
// - Does nothing if the direction doesn't match our current split direction
|
||||
// Arguments:
|
||||
// - direction: the direction to move our separator. If it's down or right,
|
||||
// we'll be increasing the size of the first of our children. Else, we'll be
|
||||
// decreasing the size of our first child.
|
||||
// Return Value:
|
||||
// - false if we couldn't resize this pane in the given direction, else true.
|
||||
bool Pane::_Resize(const Direction& direction)
|
||||
{
|
||||
if (!DirectionMatchesSplit(direction, _splitState))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float amount = .05f;
|
||||
if (direction == Direction::Right || direction == Direction::Down)
|
||||
{
|
||||
amount = -amount;
|
||||
}
|
||||
|
||||
// Make sure we're not making a pane explode here by resizing it to 0 characters.
|
||||
const bool changeWidth = _splitState == SplitState::Vertical;
|
||||
|
||||
const Size actualSize{ gsl::narrow_cast<float>(_root.ActualWidth()),
|
||||
gsl::narrow_cast<float>(_root.ActualHeight()) };
|
||||
// actualDimension is the size in DIPs of this pane in the direction we're
|
||||
// resizing.
|
||||
auto actualDimension = changeWidth ? actualSize.Width : actualSize.Height;
|
||||
actualDimension -= PaneSeparatorSize;
|
||||
|
||||
const auto firstMinSize = _firstChild->_GetMinSize();
|
||||
const auto secondMinSize = _secondChild->_GetMinSize();
|
||||
|
||||
// These are the minimum amount of space we need for each of our children
|
||||
const auto firstMinDimension = changeWidth ? firstMinSize.Width : firstMinSize.Height;
|
||||
const auto secondMinDimension = changeWidth ? secondMinSize.Width : secondMinSize.Height;
|
||||
|
||||
const auto firstMinPercent = firstMinDimension / actualDimension;
|
||||
const auto secondMinPercent = secondMinDimension / actualDimension;
|
||||
|
||||
// Make sure that the first pane doesn't get bigger than the space we need
|
||||
// to reserve for the second.
|
||||
const auto firstMaxPercent = 1.0f - secondMinPercent;
|
||||
|
||||
_firstPercent = std::clamp(_firstPercent.value() - amount, firstMinPercent, firstMaxPercent);
|
||||
// Update the other child to fill the remaining percent
|
||||
_secondPercent = 1.0f - _firstPercent.value();
|
||||
|
||||
// Resize our columns to match the new percentages.
|
||||
ResizeContent(actualSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Moves the separator between panes, as to resize each child on either size
|
||||
// of the separator. Tries to move a separator in the given direction. The
|
||||
// separator moved is the separator that's closest depth-wise to the
|
||||
// currently focused pane, that's also in the correct direction to be moved.
|
||||
// If there isn't such a separator, then this method returns false, as we
|
||||
// couldn't handle the resize.
|
||||
// Arguments:
|
||||
// - direction: The direction to move the separator in.
|
||||
// Return Value:
|
||||
// - true if we or a child handled this resize request.
|
||||
bool Pane::ResizePane(const Direction& direction)
|
||||
{
|
||||
// If we're a leaf, do nothing. We can't possibly have a descendant with a
|
||||
// separator the correct direction.
|
||||
if (_IsLeaf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if either our first or second child is the currently focused leaf.
|
||||
// If it is, and the requested resize direction matches our separator, then
|
||||
// we're the pane that needs to adjust its separator.
|
||||
// If our separator is the wrong direction, then we can't handle it.
|
||||
const bool firstIsFocused = _firstChild->_IsLeaf() && _firstChild->_lastFocused;
|
||||
const bool secondIsFocused = _secondChild->_IsLeaf() && _secondChild->_lastFocused;
|
||||
if (firstIsFocused || secondIsFocused)
|
||||
{
|
||||
return _Resize(direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If neither of our children were the focused leaf, then recurse into
|
||||
// our children and see if they can handle the resize.
|
||||
// For each child, if it has a focused descendant, try having that child
|
||||
// handle the resize.
|
||||
// If the child wasn't able to handle the resize, it's possible that
|
||||
// there were no descendants with a separator the correct direction. If
|
||||
// our separator _is_ the correct direction, then we should be the pane
|
||||
// to resize. Otherwise, just return false, as we couldn't handle it
|
||||
// either.
|
||||
if ((!_firstChild->_IsLeaf()) && _firstChild->_HasFocusedChild())
|
||||
{
|
||||
return _firstChild->ResizePane(direction) || _Resize(direction);
|
||||
}
|
||||
else if ((!_secondChild->_IsLeaf()) && _secondChild->_HasFocusedChild())
|
||||
{
|
||||
return _secondChild->ResizePane(direction) || _Resize(direction);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when our attached control is closed. Triggers listeners to our close
|
||||
// event, if we're a leaf pane.
|
||||
@@ -566,61 +415,6 @@ void Pane::_SetupChildCloseHandlers()
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane. There are three total
|
||||
// row/cols. The middle one is for the separator. The first and third are for
|
||||
// each of the child panes, and are given a size in pixels, based off the
|
||||
// availiable space, and the percent of the space they respectively consume,
|
||||
// which is stored in _firstPercent and _secondPercent.
|
||||
// - Does nothing if our split state is currently set to SplitState::None
|
||||
// Arguments:
|
||||
// - rootSize: The dimensions in pixels that this pane (and its children should consume.)
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Pane::_CreateRowColDefinitions(const Size& rootSize)
|
||||
{
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
_root.ColumnDefinitions().Clear();
|
||||
|
||||
// Create three columns in this grid: one for each pane, and one for the separator.
|
||||
auto separatorColDef = Controls::ColumnDefinition();
|
||||
separatorColDef.Width(GridLengthHelper::Auto());
|
||||
|
||||
const auto paneSizes = _GetPaneSizes(rootSize.Width);
|
||||
|
||||
auto firstColDef = Controls::ColumnDefinition();
|
||||
firstColDef.Width(GridLengthHelper::FromPixels(paneSizes.first));
|
||||
|
||||
auto secondColDef = Controls::ColumnDefinition();
|
||||
secondColDef.Width(GridLengthHelper::FromPixels(paneSizes.second));
|
||||
|
||||
_root.ColumnDefinitions().Append(firstColDef);
|
||||
_root.ColumnDefinitions().Append(separatorColDef);
|
||||
_root.ColumnDefinitions().Append(secondColDef);
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
_root.RowDefinitions().Clear();
|
||||
|
||||
// Create three rows in this grid: one for each pane, and one for the separator.
|
||||
auto separatorRowDef = Controls::RowDefinition();
|
||||
separatorRowDef.Height(GridLengthHelper::Auto());
|
||||
|
||||
const auto paneSizes = _GetPaneSizes(rootSize.Height);
|
||||
|
||||
auto firstRowDef = Controls::RowDefinition();
|
||||
firstRowDef.Height(GridLengthHelper::FromPixels(paneSizes.first));
|
||||
|
||||
auto secondRowDef = Controls::RowDefinition();
|
||||
secondRowDef.Height(GridLengthHelper::FromPixels(paneSizes.second));
|
||||
|
||||
_root.RowDefinitions().Append(firstRowDef);
|
||||
_root.RowDefinitions().Append(separatorRowDef);
|
||||
_root.RowDefinitions().Append(secondRowDef);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes our UI for a new split in this pane. Sets up row/column
|
||||
// definitions, and initializes the separator grid. Does nothing if our split
|
||||
@@ -631,13 +425,16 @@ void Pane::_CreateRowColDefinitions(const Size& rootSize)
|
||||
// - <none>
|
||||
void Pane::_CreateSplitContent()
|
||||
{
|
||||
Size actualSize{ gsl::narrow_cast<float>(_root.ActualWidth()),
|
||||
gsl::narrow_cast<float>(_root.ActualHeight()) };
|
||||
|
||||
_CreateRowColDefinitions(actualSize);
|
||||
|
||||
if (_splitState == SplitState::Vertical)
|
||||
{
|
||||
// Create three columns in this grid: one for each pane, and one for the separator.
|
||||
auto separatorColDef = Controls::ColumnDefinition();
|
||||
separatorColDef.Width(GridLengthHelper::Auto());
|
||||
|
||||
_root.ColumnDefinitions().Append(Controls::ColumnDefinition{});
|
||||
_root.ColumnDefinitions().Append(separatorColDef);
|
||||
_root.ColumnDefinitions().Append(Controls::ColumnDefinition{});
|
||||
|
||||
// Create the pane separator
|
||||
_separatorRoot = Controls::Grid{};
|
||||
_separatorRoot.Width(PaneSeparatorSize);
|
||||
@@ -646,6 +443,14 @@ void Pane::_CreateSplitContent()
|
||||
}
|
||||
else if (_splitState == SplitState::Horizontal)
|
||||
{
|
||||
// Create three rows in this grid: one for each pane, and one for the separator.
|
||||
auto separatorRowDef = Controls::RowDefinition();
|
||||
separatorRowDef.Height(GridLengthHelper::Auto());
|
||||
|
||||
_root.RowDefinitions().Append(Controls::RowDefinition{});
|
||||
_root.RowDefinitions().Append(separatorRowDef);
|
||||
_root.RowDefinitions().Append(Controls::RowDefinition{});
|
||||
|
||||
// Create the pane separator
|
||||
_separatorRoot = Controls::Grid{};
|
||||
_separatorRoot.Height(PaneSeparatorSize);
|
||||
@@ -702,7 +507,7 @@ void Pane::SplitVertical(const GUID& profile, const TermControl& control)
|
||||
return;
|
||||
}
|
||||
|
||||
_Split(SplitState::Vertical, profile, control);
|
||||
_DoSplit(SplitState::Vertical, profile, control);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -730,7 +535,7 @@ void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
|
||||
return;
|
||||
}
|
||||
|
||||
_Split(SplitState::Horizontal, profile, control);
|
||||
_DoSplit(SplitState::Horizontal, profile, control);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -742,7 +547,7 @@ void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
|
||||
// - control: A TermControl to use in the new pane.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl& control)
|
||||
void Pane::_DoSplit(SplitState splitType, const GUID& profile, const TermControl& control)
|
||||
{
|
||||
// Lock the create/close lock so that another operation won't concurrently
|
||||
// modify our tree
|
||||
@@ -754,9 +559,6 @@ void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl&
|
||||
|
||||
_splitState = splitType;
|
||||
|
||||
_firstPercent = { Half };
|
||||
_secondPercent = { Half };
|
||||
|
||||
_CreateSplitContent();
|
||||
|
||||
// Remove any children we currently have. We can't add the existing
|
||||
@@ -783,52 +585,4 @@ void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl&
|
||||
_lastFocused = false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the size in pixels of each of our children, given the full size they
|
||||
// should fill. Accounts for the size of the separator that should be between
|
||||
// them as well.
|
||||
// Arguments:
|
||||
// - fullSize: the amount of space in pixels that should be filled by our
|
||||
// children and their separator
|
||||
// Return Value:
|
||||
// - a pair with the size of our first child and the size of our second child,
|
||||
// respectively.
|
||||
std::pair<float, float> Pane::_GetPaneSizes(const float& fullSize)
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
THROW_HR(E_FAIL);
|
||||
}
|
||||
|
||||
const auto sizeMinusSeparator = fullSize - PaneSeparatorSize;
|
||||
const auto firstSize = sizeMinusSeparator * _firstPercent.value();
|
||||
const auto secondSize = sizeMinusSeparator * _secondPercent.value();
|
||||
return { firstSize, secondSize };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the absolute minimum size that this pane can be resized to and still
|
||||
// have 1x1 character visible, in each of its children. This includes the
|
||||
// space needed for the separator.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The minimum size that this pane can be resized to and still have a visible
|
||||
// character.
|
||||
Size Pane::_GetMinSize() const
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
return _control.MinimumSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto firstSize = _firstChild->_GetMinSize();
|
||||
const auto secondSize = _secondChild->_GetMinSize();
|
||||
const auto newWidth = firstSize.Width + secondSize.Width + (_splitState == SplitState::Vertical ? PaneSeparatorSize : 0);
|
||||
const auto newHeight = firstSize.Height + secondSize.Height + (_splitState == SplitState::Horizontal ? PaneSeparatorSize : 0);
|
||||
return { newWidth, newHeight };
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_EVENT(Pane, Closed, _closedHandlers, ConnectionClosedEventArgs);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
#include <winrt/TerminalApp.h>
|
||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||
|
||||
class Pane : public std::enable_shared_from_this<Pane>
|
||||
@@ -45,8 +44,6 @@ public:
|
||||
void UpdateFocus();
|
||||
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile);
|
||||
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
bool ResizePane(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
void SplitHorizontal(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
void SplitVertical(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
@@ -61,8 +58,6 @@ private:
|
||||
std::shared_ptr<Pane> _firstChild{ nullptr };
|
||||
std::shared_ptr<Pane> _secondChild{ nullptr };
|
||||
SplitState _splitState{ SplitState::None };
|
||||
std::optional<float> _firstPercent{ std::nullopt };
|
||||
std::optional<float> _secondPercent{ std::nullopt };
|
||||
|
||||
bool _lastFocused{ false };
|
||||
std::optional<GUID> _profile{ std::nullopt };
|
||||
@@ -76,52 +71,12 @@ private:
|
||||
bool _HasFocusedChild() const noexcept;
|
||||
void _SetupChildCloseHandlers();
|
||||
|
||||
void _Split(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
void _CreateRowColDefinitions(const winrt::Windows::Foundation::Size& rootSize);
|
||||
void _DoSplit(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
void _CreateSplitContent();
|
||||
void _ApplySplitDefinitions();
|
||||
bool _Resize(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
void _CloseChild(const bool closeFirst);
|
||||
|
||||
void _FocusFirstChild();
|
||||
void _ControlClosedHandler();
|
||||
|
||||
std::pair<float, float> _GetPaneSizes(const float& fullSize);
|
||||
|
||||
winrt::Windows::Foundation::Size _GetMinSize() const;
|
||||
|
||||
// Function Description:
|
||||
// - Returns true if the given direction can be used with the given split
|
||||
// type.
|
||||
// - This is used for pane resizing (which will need a pane separator
|
||||
// that's perpendicular to the direction to be able to move the separator
|
||||
// in that direction).
|
||||
// - Additionally, it will be used for moving focus between panes, which
|
||||
// again happens _across_ a separator.
|
||||
// Arguments:
|
||||
// - direction: The Direction to compare
|
||||
// - splitType: The SplitState to compare
|
||||
// Return Value:
|
||||
// - true iff the direction is perpendicular to the splitType. False for
|
||||
// SplitState::None.
|
||||
static constexpr bool DirectionMatchesSplit(const winrt::TerminalApp::Direction& direction,
|
||||
const SplitState& splitType)
|
||||
{
|
||||
if (splitType == SplitState::None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (splitType == SplitState::Horizontal)
|
||||
{
|
||||
return direction == winrt::TerminalApp::Direction::Up ||
|
||||
direction == winrt::TerminalApp::Direction::Down;
|
||||
}
|
||||
else if (splitType == SplitState::Vertical)
|
||||
{
|
||||
return direction == winrt::TerminalApp::Direction::Left ||
|
||||
direction == winrt::TerminalApp::Direction::Right;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
using namespace TerminalApp;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
using namespace ::Microsoft::Console;
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
@@ -19,7 +21,6 @@ static constexpr std::string_view ColorSchemeKeyOld{ "colorscheme" };
|
||||
static constexpr std::string_view ForegroundKey{ "foreground" };
|
||||
static constexpr std::string_view BackgroundKey{ "background" };
|
||||
static constexpr std::string_view ColorTableKey{ "colorTable" };
|
||||
static constexpr std::string_view TabTitleKey{ "tabTitle" };
|
||||
static constexpr std::string_view HistorySizeKey{ "historySize" };
|
||||
static constexpr std::string_view SnapOnInputKey{ "snapOnInput" };
|
||||
static constexpr std::string_view CursorColorKey{ "cursorColor" };
|
||||
@@ -70,7 +71,6 @@ Profile::Profile(const winrt::guid& guid) :
|
||||
_defaultForeground{},
|
||||
_defaultBackground{},
|
||||
_colorTable{},
|
||||
_tabTitle{},
|
||||
_historySize{ DEFAULT_HISTORY_SIZE },
|
||||
_snapOnInput{ true },
|
||||
_cursorColor{ DEFAULT_CURSOR_COLOR },
|
||||
@@ -271,11 +271,6 @@ Json::Value Profile::ToJson() const
|
||||
root[JsonKey(IconKey)] = icon;
|
||||
}
|
||||
|
||||
if (_tabTitle)
|
||||
{
|
||||
root[JsonKey(TabTitleKey)] = winrt::to_string(_tabTitle.value());
|
||||
}
|
||||
|
||||
if (_startingDirectory)
|
||||
{
|
||||
root[JsonKey(StartingDirectoryKey)] = winrt::to_string(_startingDirectory.value());
|
||||
@@ -374,10 +369,6 @@ Profile Profile::FromJson(const Json::Value& json)
|
||||
{
|
||||
result._cursorShape = _ParseCursorShape(GetWstringFromJson(cursorShape));
|
||||
}
|
||||
if (auto tabTitle{ json[JsonKey(TabTitleKey)] })
|
||||
{
|
||||
result._tabTitle = GetWstringFromJson(tabTitle);
|
||||
}
|
||||
|
||||
// Control Settings
|
||||
if (auto commandline{ json[JsonKey(CommandlineKey)] })
|
||||
@@ -486,15 +477,6 @@ bool Profile::HasIcon() const noexcept
|
||||
return _icon.has_value();
|
||||
}
|
||||
|
||||
// Method Description
|
||||
// - Sets this profile's tab title.
|
||||
// Arguments:
|
||||
// - tabTitle: the tab title
|
||||
void Profile::SetTabTitle(std::wstring tabTitle) noexcept
|
||||
{
|
||||
_tabTitle = tabTitle;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets this profile's icon path.
|
||||
// Arguments:
|
||||
@@ -526,26 +508,6 @@ std::wstring_view Profile::GetName() const noexcept
|
||||
return _name;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns true if profile's custom tab title is set, if one is set. Otherwise returns false.
|
||||
// Return Value:
|
||||
// - true if this profile's custom tab title is set. Otherwise returns false.
|
||||
bool Profile::HasTabTitle() const noexcept
|
||||
{
|
||||
return _tabTitle.has_value();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the custom tab title, if one is set. Otherwise returns the empty string.
|
||||
// Return Value:
|
||||
// - this profile's custom tab title, if one is set. Otherwise returns the empty string.
|
||||
std::wstring_view Profile::GetTabTitle() const noexcept
|
||||
{
|
||||
return HasTabTitle() ?
|
||||
std::wstring_view{ _tabTitle.value().c_str(), _tabTitle.value().size() } :
|
||||
std::wstring_view{ L"", 0 };
|
||||
}
|
||||
|
||||
bool Profile::GetCloseOnExit() const noexcept
|
||||
{
|
||||
return _closeOnExit;
|
||||
|
||||
@@ -36,12 +36,9 @@ public:
|
||||
|
||||
GUID GetGuid() const noexcept;
|
||||
std::wstring_view GetName() const noexcept;
|
||||
bool HasTabTitle() const noexcept;
|
||||
std::wstring_view GetTabTitle() const noexcept;
|
||||
|
||||
void SetFontFace(std::wstring fontFace) noexcept;
|
||||
void SetColorScheme(std::optional<std::wstring> schemeName) noexcept;
|
||||
void SetTabTitle(std::wstring tabTitle) noexcept;
|
||||
void SetAcrylicOpacity(double opacity) noexcept;
|
||||
void SetCommandline(std::wstring cmdline) noexcept;
|
||||
void SetStartingDirectory(std::wstring startingDirectory) noexcept;
|
||||
@@ -74,7 +71,6 @@ private:
|
||||
std::optional<uint32_t> _defaultForeground;
|
||||
std::optional<uint32_t> _defaultBackground;
|
||||
std::array<uint32_t, COLOR_TABLE_SIZE> _colorTable;
|
||||
std::optional<std::wstring> _tabTitle;
|
||||
int32_t _historySize;
|
||||
bool _snapOnInput;
|
||||
uint32_t _cursorColor;
|
||||
|
||||
@@ -166,7 +166,7 @@ void Tab::SetTabText(const winrt::hstring& text)
|
||||
// Copy the hstring, so we don't capture a dead reference
|
||||
winrt::hstring textCopy{ text };
|
||||
_tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [text = std::move(textCopy), this]() {
|
||||
_tabViewItem.Header(winrt::box_value(text));
|
||||
_tabViewItem.Header(text);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -213,28 +213,4 @@ void Tab::AddHorizontalSplit(const GUID& profile, TermControl& control)
|
||||
_rootPane->SplitHorizontal(profile, control);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the size of our panes to fill the new given size. This happens when
|
||||
// the window is resized.
|
||||
// Arguments:
|
||||
// - newSize: the amount of space that the panes have to fill now.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Tab::ResizeContent(const winrt::Windows::Foundation::Size& newSize)
|
||||
{
|
||||
_rootPane->ResizeContent(newSize);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Attempt to move a separator between panes, as to resize each child on
|
||||
// either size of the separator. See Pane::ResizePane for details.
|
||||
// Arguments:
|
||||
// - direction: The direction to move the separator in.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Tab::ResizePane(const winrt::TerminalApp::Direction& direction)
|
||||
{
|
||||
_rootPane->ResizePane(direction);
|
||||
}
|
||||
|
||||
DEFINE_EVENT(Tab, Closed, _closedHandlers, ConnectionClosedEventArgs);
|
||||
|
||||
@@ -23,8 +23,6 @@ public:
|
||||
void AddHorizontalSplit(const GUID& profile, winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||
|
||||
void UpdateFocus();
|
||||
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
|
||||
void ResizePane(const winrt::TerminalApp::Direction& direction);
|
||||
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile);
|
||||
winrt::hstring GetFocusedTitle() const;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
<!-- build a dll, not exe (Application) -->
|
||||
@@ -17,37 +15,90 @@
|
||||
<ProjectName>TerminalApp</ProjectName>
|
||||
<RootNamespace>TerminalApp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- ========================= XAML files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT XAML FILES HERE! Put them in TerminalAppLib.vcxproj -->
|
||||
<!-- HERE BE DRAGONS:
|
||||
For any types that use XAML information, if their .idl, .cpp, and .h
|
||||
aren't all marked DependentUpon the corresponding .xaml file,
|
||||
XamlTypeInfo.g.h won't pick it up correctly.
|
||||
-->
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<!-- When we add other user controls, they should go in here as so: -->
|
||||
<!-- <ItemGroup>
|
||||
<Page Include="MyUserControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup> -->
|
||||
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- Only put headers for winrt types in here. Don't put other header files
|
||||
in here - put them in TerminalAppLib.vcxproj instead! -->
|
||||
<ClInclude Include="Tab.h" />
|
||||
<ClInclude Include="Pane.h" />
|
||||
<ClInclude Include="ColorScheme.h" />
|
||||
<ClInclude Include="GlobalAppSettings.h" />
|
||||
<ClInclude Include="Profile.h" />
|
||||
<ClInclude Include="CascadiaSettings.h" />
|
||||
<ClInclude Include="AppKeyBindingsSerialization.h" />
|
||||
<ClInclude Include="KeyChordSerialization.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="TerminalPage.h" />
|
||||
<ClInclude Include="MinMaxCloseControl.h" />
|
||||
<ClInclude Include="AppKeyBindings.h" />
|
||||
<ClInclude Include="App.h" />
|
||||
<ClInclude Include="AppKeyBindings.h">
|
||||
<DependentUpon>AppKeyBindings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="App.h">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- Don't put source files in here - put them in TerminalAppLib.vcxproj instead! -->
|
||||
<ClCompile Include="Tab.cpp" />
|
||||
<ClCompile Include="Pane.cpp" />
|
||||
<ClCompile Include="ColorScheme.cpp" />
|
||||
<ClCompile Include="GlobalAppSettings.cpp" />
|
||||
<ClCompile Include="Profile.cpp" />
|
||||
<ClCompile Include="CascadiaSettings.cpp" />
|
||||
<ClCompile Include="CascadiaSettingsSerialization.cpp" />
|
||||
<ClCompile Include="AppKeyBindingsSerialization.cpp" />
|
||||
<ClCompile Include="KeyChordSerialization.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppKeyBindings.cpp">
|
||||
<DependentUpon>AppKeyBindings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="App.cpp">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
|
||||
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
|
||||
you want to use jsoncpp -->
|
||||
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= idl Files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- DON'T PUT IDL FILES HERE! Put them in TerminalApp.vcxproj -->
|
||||
<Midl Include="App.idl">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="AppKeyBindings.idl" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Misc Files ======================== -->
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="TerminalApp.def" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<ItemGroup>
|
||||
<!--
|
||||
@@ -58,31 +109,18 @@
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj">
|
||||
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj">
|
||||
<Project>{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}</Project>
|
||||
</ProjectReference>
|
||||
|
||||
<!-- The midl compiler however, _will_ aggregate our winmd dependencies
|
||||
somehow. So make sure to only include top-level dependencies here (don't
|
||||
include Settings and Connection, since Control will include them for us) -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
|
||||
<!-- Reference TerminalAppLib here, so we can use it's TerminalApp.winmd as
|
||||
our TerminalApp.winmd. This didn't work correctly in VS2017, you'd need to
|
||||
manually reference the lib -->
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" >
|
||||
<!-- This is needed to be able to reference the XamlApplication type. -->
|
||||
<ProjectReference Include="..\Microsoft.UI.Xaml.Markup\Microsoft.UI.Xaml.Markup.vcxproj">
|
||||
<Project>{015a0047-772d-4f1a-88c9-45c18f0adfb6}</Project>
|
||||
<Private>true</Private>
|
||||
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- A small helper for paths to the compiled cppwinrt projects -->
|
||||
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
|
||||
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
DON'T REDIRECT OUR OUTPUT.
|
||||
@@ -95,12 +133,18 @@
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib;WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalPage.h"
|
||||
|
||||
#include "TerminalPage.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalPage::TerminalPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Bound in the Xaml editor to the [+] button.
|
||||
// Arguments:
|
||||
// - sender
|
||||
// - event arguments
|
||||
void TerminalPage::OnNewTabButtonClick(IInspectable const&, Controls::SplitButtonClickEventArgs const&)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Microsoft.UI.Xaml.Controls.h"
|
||||
|
||||
#include "TerminalPage.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalPage : TerminalPageT<TerminalPage>
|
||||
{
|
||||
TerminalPage();
|
||||
|
||||
void OnNewTabButtonClick(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SplitButtonClickEventArgs const& args);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
struct TerminalPage : TerminalPageT<TerminalPage, implementation::TerminalPage>
|
||||
{
|
||||
};
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
TerminalPage();
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information. -->
|
||||
<Page
|
||||
x:Class="TerminalApp.TerminalPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid x:Name="TabRow" Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<mux:TabView x:Name="TabView" Grid.Column="0" />
|
||||
|
||||
<SplitButton
|
||||
x:Name="NewTabButton"
|
||||
Grid.Column="1"
|
||||
Click="OnNewTabButtonClick"
|
||||
Background="{ThemeResource SystemChromeLowColor}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Left">
|
||||
<Viewbox MaxHeight="15"
|
||||
MaxWidth="15">
|
||||
<SymbolIcon Symbol="Add" />
|
||||
</Viewbox>
|
||||
</SplitButton>
|
||||
|
||||
<local:MinMaxCloseControl
|
||||
x:Name="MinMaxCloseControl"
|
||||
Grid.Column="3"
|
||||
HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="TabContent" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,280 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
<!-- ========================= CppWinRT Metadata ======================== -->
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
<!--
|
||||
This is an override that, puzzlingly, _forces XBF (XAML binary) embedding_.
|
||||
We have to do this to overcome a layout issue in the WAP packaging project.
|
||||
When we do this, the XBF ends up in resources.pri.
|
||||
-->
|
||||
<DisableEmbeddedXbf>false</DisableEmbeddedXbf>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
|
||||
|
||||
<!-- ========================= XAML files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- HERE BE DRAGONS:
|
||||
For any types that use XAML information, if their .idl and .h aren't
|
||||
marked DependentUpon the corresponding .xaml file, XamlTypeInfo.g.h won't
|
||||
pick it up correctly. -->
|
||||
<ApplicationDefinition Include="..\App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<!-- When we add other user controls, they should go in here as so: -->
|
||||
<ItemGroup>
|
||||
<Page Include="../MinMaxCloseControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="../TerminalPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="../App.base.h" />
|
||||
<ClInclude Include="../MinMaxCloseControl.h">
|
||||
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="../TerminalPage.h">
|
||||
<DependentUpon>../TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="../Tab.h" />
|
||||
<ClInclude Include="../Pane.h" />
|
||||
<ClInclude Include="../ColorScheme.h" />
|
||||
<ClInclude Include="../GlobalAppSettings.h" />
|
||||
<ClInclude Include="../Profile.h" />
|
||||
<ClInclude Include="../CascadiaSettings.h" />
|
||||
<ClInclude Include="../AppKeyBindingsSerialization.h" />
|
||||
<ClInclude Include="../KeyChordSerialization.h" />
|
||||
<ClInclude Include="../Utils.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="../AppKeyBindings.h" />
|
||||
<ClInclude Include="../App.h" >
|
||||
<DependentUpon>../App.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="../MinMaxCloseControl.cpp">
|
||||
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../TerminalPage.cpp">
|
||||
<DependentUpon>../TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../Tab.cpp" />
|
||||
<ClCompile Include="../Pane.cpp" />
|
||||
<ClCompile Include="../ColorScheme.cpp" />
|
||||
<ClCompile Include="../GlobalAppSettings.cpp" />
|
||||
<ClCompile Include="../Profile.cpp" />
|
||||
<ClCompile Include="../CascadiaSettings.cpp" />
|
||||
<ClCompile Include="../CascadiaSettingsSerialization.cpp" />
|
||||
<ClCompile Include="../AppKeyBindingsSerialization.cpp" />
|
||||
<ClCompile Include="../KeyChordSerialization.cpp" />
|
||||
<ClCompile Include="../Utils.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../AppKeyBindings.cpp" >
|
||||
<DependentUpon>../AppKeyBindings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="../App.cpp" >
|
||||
<DependentUpon>../App.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
|
||||
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
|
||||
you want to use jsoncpp -->
|
||||
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= idl Files ======================== -->
|
||||
<ItemGroup>
|
||||
<!-- If you add idl files here, make sure to include their implementation's
|
||||
header in TerminalApp.vcxproj (as well as in this file) -->
|
||||
<Midl Include="../App.idl" >
|
||||
<DependentUpon>../App.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="../AppKeyBindings.idl" />
|
||||
<Midl Include="../MinMaxCloseControl.idl">
|
||||
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="../TerminalPage.idl">
|
||||
<DependentUpon>../TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Misc Files ======================== -->
|
||||
<ItemGroup>
|
||||
<None Include="../packages.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<ItemGroup>
|
||||
<!--
|
||||
the packaging project won't recurse through our dependencies, you have to
|
||||
make sure that if you add a cppwinrt dependency to any of these projects,
|
||||
you also update all the consumers
|
||||
-->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
|
||||
|
||||
<!-- For whatever reason, we can't include the TerminalControl and
|
||||
TerminalSettings projects' winmds via project references. So we'll have to
|
||||
manually include the winmds as References below -->
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- A small helper for paths to the compiled cppwinrt projects -->
|
||||
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
|
||||
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This is a hack to get the ARM64 CI build working. See
|
||||
https://github.com/Microsoft/msbuild/issues/3746 - it looks like MsBuild
|
||||
just has a bug in it.-->
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>Warning</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Manually add references to each of our dependent winmds. Mark them as
|
||||
private=false and CopyLocalSatelliteAssemblies=false, so that we don't
|
||||
propogate them upwards (which can make referencing this project result in
|
||||
duplicate type definitions)-->
|
||||
|
||||
<Reference Include="Microsoft.Terminal.Settings">
|
||||
<HintPath>$(_BinRoot)TerminalSettings\Microsoft.Terminal.Settings.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
|
||||
<Reference Include="Microsoft.Terminal.TerminalConnection">
|
||||
<HintPath>$(_BinRoot)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
|
||||
<Reference Include="Microsoft.Terminal.TerminalControl">
|
||||
<HintPath>$(_BinRoot)TerminalControl\Microsoft.Terminal.TerminalControl.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ====================== Compiler & Linker Flags ===================== -->
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
|
||||
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!-- ========================= Globals ======================== -->
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CA5CAD1A-9A12-429C-B551-8562EC954746}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>TerminalApp</RootNamespace>
|
||||
<ProjectName>TerminalAppLib</ProjectName>
|
||||
<TargetName>TerminalAppLib</TargetName>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
DON'T REDIRECT OUR OUTPUT.
|
||||
Setting this will tell cppwinrt.build.post.props to copy our output from
|
||||
the default OutDir up one level, so the wapproj will be able to find it.
|
||||
-->
|
||||
<NoOutputRedirection>true</NoOutputRedirection>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<!-- Manually include MUX here, instead of importing its targets file. We need
|
||||
to reference its winmd, but very specifically with the
|
||||
CopyLocalSatelliteAssemblies and Private properties set to false, as to not
|
||||
have projects including us double-including MUX's .winmd. The following blob
|
||||
is taken straight from the MUX build targets, with the afformentioned
|
||||
changes.-->
|
||||
<PropertyGroup>
|
||||
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
|
||||
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
|
||||
<_MUXRoot>$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\</_MUXRoot>
|
||||
<_MUXAppRoot>$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\</_MUXAppRoot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Microsoft.UI.XAML -->
|
||||
<Reference Include="$(_MUXRoot)lib\uap10.0\Microsoft.UI.Xaml.winmd">
|
||||
<Implementation>Microsoft.UI.Xaml.dll</Implementation>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.dll" />
|
||||
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.pri" />
|
||||
|
||||
<!-- Microsoft.UI.XAML.Application -->
|
||||
<Reference Include="$(_MUXAppRoot)lib\uap10.0\Microsoft.Toolkit.Win32.UI.XamlHost.winmd">
|
||||
<Implementation>Microsoft.Toolkit.Win32.UI.XamlHost.dll</Implementation>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<ReferenceCopyLocalPaths Include="$(_MUXAppRoot)lib\uap10.0\Microsoft.Toolkit.Win32.UI.XamlHost.*" />
|
||||
<ReferenceCopyLocalPaths Include="$(_MUXAppRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.Toolkit.Win32.UI.XamlHost.*" />
|
||||
</ItemGroup>
|
||||
<!-- End MUX import -->
|
||||
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
</Target>
|
||||
|
||||
|
||||
<!--
|
||||
By default, the PRI file will contain resource paths beginning with the
|
||||
project name. Since we enabled XBF embedding, this *also* includes App.xbf.
|
||||
Well, App.xbf is hardcoded by the framework to be found at the resource ROOT.
|
||||
To make that happen, we have to disable the prepending of the project name
|
||||
to the App xaml files.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<_GenerateProjectPriFileDependsOn>OpenConsolePlaceAppXbfAtRootOfResourceTree;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="OpenConsolePlaceAppXbfAtRootOfResourceTree" DependsOnTargets="GetPackagingOutputs">
|
||||
<ItemGroup>
|
||||
<_RelocatedAppXamlData Include="@(PackagingOutputs)" Condition="'%(Filename)' == 'App' and ('%(Extension)' == '.xaml' or '%(Extension)' == '.xbf')" />
|
||||
<PackagingOutputs Remove="@(_RelocatedAppXamlData)" />
|
||||
<PackagingOutputs Include="@(_RelocatedAppXamlData)">
|
||||
<TargetPath>%(Filename)%(Extension)</TargetPath>
|
||||
</PackagingOutputs>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// pch.h
|
||||
// Header for platform projection include files
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <LibraryIncludes.h>
|
||||
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
|
||||
// SDK definition of this function, so the only fix is to undef it.
|
||||
// from WinBase.h
|
||||
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <unknwn.h>
|
||||
|
||||
#include <hstring.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Resources.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/windows.ui.core.h>
|
||||
#include <winrt/Windows.ui.input.h>
|
||||
#include <winrt/Windows.UI.Text.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
#include <winrt/Windows.ui.xaml.input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Hosting.h>
|
||||
#include "winrt/Windows.UI.Xaml.Markup.h"
|
||||
#include "winrt/Windows.UI.Xaml.Documents.h"
|
||||
|
||||
#include <winrt/Microsoft.Toolkit.Win32.UI.XamlHost.h>
|
||||
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
// Including TraceLogging essentials for the binary
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include <winmeta.h>
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
|
||||
#include <telemetry\ProjectTelemetry.h>
|
||||
#include <TraceLoggingActivity.h>
|
||||
|
||||
// JsonCpp
|
||||
#include <json.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
#include <filesystem>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.1.190405001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -7,6 +7,47 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// This file can be empty - the pch.h in TerminalApp/lib does the heavy lifting
|
||||
// of including all the headers we need. As this project is just a dll wrapper,
|
||||
// we don't actually need anything in here.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <LibraryIncludes.h>
|
||||
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
|
||||
// SDK definition of this function, so the only fix is to undef it.
|
||||
// from WinBase.h
|
||||
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
|
||||
#include <unknwn.h>
|
||||
|
||||
#include <hstring.h>
|
||||
|
||||
#include <winrt/coroutine.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Resources.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/windows.ui.core.h>
|
||||
#include <winrt/Windows.ui.input.h>
|
||||
#include <winrt/Windows.UI.Text.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
#include <winrt/Windows.ui.xaml.input.h>
|
||||
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
// Including TraceLogging essentials for the binary
|
||||
#include <TraceLoggingProvider.h>
|
||||
#include <winmeta.h>
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
|
||||
#include <telemetry\ProjectTelemetry.h>
|
||||
#include <TraceLoggingActivity.h>
|
||||
|
||||
// JsonCpp
|
||||
#include <json.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
#include <filesystem>
|
||||
|
||||
@@ -37,23 +37,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
}
|
||||
}
|
||||
|
||||
ConhostConnection::ConhostConnection(const uint64_t server,
|
||||
const uint32_t initialRows,
|
||||
const uint32_t initialCols,
|
||||
const guid& initialGuid) :
|
||||
_initialRows{ initialRows },
|
||||
_initialCols{ initialCols },
|
||||
_commandline{},
|
||||
_startingDirectory{},
|
||||
_guid{ initialGuid },
|
||||
_hServer{ reinterpret_cast<HANDLE>(server) }
|
||||
{
|
||||
if (_guid == guid{})
|
||||
{
|
||||
_guid = Utils::CreateGuid();
|
||||
}
|
||||
}
|
||||
|
||||
winrt::guid ConhostConnection::Guid() const noexcept
|
||||
{
|
||||
return _guid;
|
||||
@@ -88,12 +71,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
startingDirectory = _startingDirectory;
|
||||
}
|
||||
|
||||
std::optional<HANDLE> server;
|
||||
if (_hServer)
|
||||
{
|
||||
server = _hServer.get();
|
||||
}
|
||||
|
||||
EnvironmentVariableMapW extraEnvVars;
|
||||
{
|
||||
// Convert connection Guid to string and ignore the enclosing '{}'.
|
||||
@@ -111,7 +88,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
startingDirectory,
|
||||
static_cast<short>(_initialCols),
|
||||
static_cast<short>(_initialRows),
|
||||
server,
|
||||
&_inPipe,
|
||||
&_outPipe,
|
||||
&_signalPipe,
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
struct ConhostConnection : ConhostConnectionT<ConhostConnection>
|
||||
{
|
||||
ConhostConnection(const hstring& cmdline, const hstring& startingDirectory, const uint32_t rows, const uint32_t cols, const guid& guid);
|
||||
ConhostConnection(const uint64_t server, const uint32_t rows, const uint32_t cols, const guid& guid);
|
||||
|
||||
winrt::event_token TerminalOutput(TerminalConnection::TerminalOutputEventArgs const& handler);
|
||||
void TerminalOutput(winrt::event_token const& token) noexcept;
|
||||
@@ -42,7 +41,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
wil::unique_handle _hOutputThread;
|
||||
wil::unique_process_information _piConhost;
|
||||
wil::unique_handle _hJob;
|
||||
wil::unique_handle _hServer;
|
||||
|
||||
static DWORD WINAPI StaticOutputThreadProc(LPVOID lpParameter);
|
||||
DWORD _OutputThread();
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Microsoft.Terminal.TerminalConnection
|
||||
runtimeclass ConhostConnection : ITerminalConnection
|
||||
{
|
||||
ConhostConnection(String cmdline, String startingDirectory, UInt32 rows, UInt32 columns, Guid guid);
|
||||
ConhostConnection(UInt64 server, UInt32 rows, UInt32 columns, Guid guid);
|
||||
|
||||
Guid Guid { get; };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -22,12 +22,12 @@ using namespace winrt::Microsoft::Terminal::Settings;
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
TermControl::TermControl() :
|
||||
TermControl(Settings::TerminalSettings{}, TerminalConnection::ITerminalConnection{ nullptr })
|
||||
TermControl(Settings::TerminalSettings{})
|
||||
{
|
||||
}
|
||||
|
||||
TermControl::TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection) :
|
||||
_connection{ connection },
|
||||
TermControl::TermControl(Settings::IControlSettings settings) :
|
||||
_connection{ TerminalConnection::ConhostConnection(winrt::to_hstring("cmd.exe"), winrt::hstring(), 30, 80, winrt::guid()) },
|
||||
_initializedTerminal{ false },
|
||||
_root{ nullptr },
|
||||
_controlRoot{ nullptr },
|
||||
@@ -39,9 +39,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
_actualFont{ DEFAULT_FONT_FACE.c_str(), 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
|
||||
_touchAnchor{ std::nullopt },
|
||||
_leadingSurrogate{},
|
||||
_cursorTimer{},
|
||||
_lastMouseClick{},
|
||||
_lastMouseClickPos{}
|
||||
_cursorTimer{}
|
||||
{
|
||||
_Create();
|
||||
}
|
||||
@@ -95,18 +93,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
Controls::Grid::SetColumn(swapChainPanel, 0);
|
||||
Controls::Grid::SetColumn(_scrollBar, 1);
|
||||
|
||||
Controls::Grid root{};
|
||||
Controls::Image bgImageLayer{};
|
||||
root.Children().Append(bgImageLayer);
|
||||
root.Children().Append(container);
|
||||
|
||||
_root = root;
|
||||
_bgImageLayer = bgImageLayer;
|
||||
|
||||
_root = container;
|
||||
_swapChainPanel = swapChainPanel;
|
||||
_controlRoot.Content(_root);
|
||||
|
||||
_ApplyUISettings();
|
||||
_ApplyConnectionSettings();
|
||||
|
||||
// These are important:
|
||||
// 1. When we get tapped, focus us
|
||||
@@ -180,9 +172,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
uint32_t bg = _settings.DefaultBackground();
|
||||
_BackgroundColorChanged(bg);
|
||||
|
||||
// Apply padding as swapChainPanel's margin
|
||||
// Apply padding to the root Grid
|
||||
auto thickness = _ParseThicknessFromPadding(_settings.Padding());
|
||||
_swapChainPanel.Margin(thickness);
|
||||
_root.Padding(thickness);
|
||||
|
||||
// Initialize our font information.
|
||||
const auto* fontFace = _settings.FontFace().c_str();
|
||||
@@ -198,11 +190,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Set up each layer's brush used to display the control's background.
|
||||
// - Set up the brush used to display the control's background.
|
||||
// - Respects the settings for acrylic, background image and opacity from
|
||||
// _settings.
|
||||
// * If acrylic is not enabled, setup a solid color background, otherwise
|
||||
// use bgcolor as acrylic's tint
|
||||
// * Prioritizes the acrylic background if chosen, respecting acrylicOpacity
|
||||
// from _settings.
|
||||
// * If acrylic is not enabled and a backgroundImage is present, it is used,
|
||||
// respecting the opacity and stretch mode settings from _settings.
|
||||
// * Falls back to a solid color background from _settings if acrylic is not
|
||||
// enabled and no background image is present.
|
||||
// - Avoids image flickering and acrylic brush redraw if settings are changed
|
||||
// but the appropriate brush is still in place.
|
||||
// - Does not apply background color outside of acrylic mode;
|
||||
@@ -247,20 +243,23 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
_root.Background(acrylic);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Media::SolidColorBrush solidColor{};
|
||||
_root.Background(solidColor);
|
||||
}
|
||||
|
||||
if (!_settings.BackgroundImage().empty())
|
||||
else if (!_settings.BackgroundImage().empty())
|
||||
{
|
||||
Windows::Foundation::Uri imageUri{ _settings.BackgroundImage() };
|
||||
|
||||
// Check if the existing brush is an image brush, and if not
|
||||
// construct a new one
|
||||
auto brush = _root.Background().try_as<Media::ImageBrush>();
|
||||
|
||||
if (brush == nullptr)
|
||||
{
|
||||
brush = Media::ImageBrush{};
|
||||
}
|
||||
|
||||
// Check if the image brush is already pointing to the image
|
||||
// in the modified settings; if it isn't (or isn't there),
|
||||
// set a new image source for the brush
|
||||
auto imageSource = _bgImageLayer.Source().try_as<Media::Imaging::BitmapImage>();
|
||||
auto imageSource = brush.ImageSource().try_as<Media::Imaging::BitmapImage>();
|
||||
|
||||
if (imageSource == nullptr ||
|
||||
imageSource.UriSource() == nullptr ||
|
||||
@@ -271,18 +270,23 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// may well be both large and somewhere out on the
|
||||
// internet.
|
||||
Media::Imaging::BitmapImage image(imageUri);
|
||||
_bgImageLayer.Source(image);
|
||||
_bgImageLayer.HorizontalAlignment(HorizontalAlignment::Center);
|
||||
_bgImageLayer.VerticalAlignment(VerticalAlignment::Center);
|
||||
brush.ImageSource(image);
|
||||
}
|
||||
|
||||
// Apply stretch and opacity settings
|
||||
_bgImageLayer.Stretch(_settings.BackgroundImageStretchMode());
|
||||
_bgImageLayer.Opacity(_settings.BackgroundImageOpacity());
|
||||
brush.Stretch(_settings.BackgroundImageStretchMode());
|
||||
brush.Opacity(_settings.BackgroundImageOpacity());
|
||||
|
||||
// Apply brush if it isn't already there
|
||||
if (_root.Background() != brush)
|
||||
{
|
||||
_root.Background(brush);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgImageLayer.Source(nullptr);
|
||||
Media::SolidColorBrush solidColor{};
|
||||
_root.Background(solidColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,22 +309,50 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
bgColor.B = B;
|
||||
bgColor.A = 255;
|
||||
|
||||
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
|
||||
if (_settings.UseAcrylic())
|
||||
{
|
||||
acrylic.FallbackColor(bgColor);
|
||||
acrylic.TintColor(bgColor);
|
||||
}
|
||||
else if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
|
||||
{
|
||||
solidColor.Color(bgColor);
|
||||
}
|
||||
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
|
||||
{
|
||||
acrylic.FallbackColor(bgColor);
|
||||
acrylic.TintColor(bgColor);
|
||||
}
|
||||
|
||||
// Set the default background as transparent to prevent the
|
||||
// DX layer from overwriting the background image or acrylic effect
|
||||
_settings.DefaultBackground(ARGB(0, R, G, B));
|
||||
// If we're acrylic, we want to make sure that the default BG color
|
||||
// is transparent, so we can see the acrylic effect on text with the
|
||||
// default BG color.
|
||||
_settings.DefaultBackground(ARGB(0, R, G, B));
|
||||
}
|
||||
else if (!_settings.BackgroundImage().empty())
|
||||
{
|
||||
// This currently applies no changes to the image background
|
||||
// brush itself.
|
||||
|
||||
// Set the default background as transparent to prevent the
|
||||
// DX layer from overwriting the background image
|
||||
_settings.DefaultBackground(ARGB(0, R, G, B));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
|
||||
{
|
||||
solidColor.Color(bgColor);
|
||||
}
|
||||
|
||||
_settings.DefaultBackground(RGB(R, G, B));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a connection based on the values in our settings object.
|
||||
// * Gets the commandline and working directory out of the _settings and
|
||||
// creates a ConhostConnection with the given commandline and starting
|
||||
// directory.
|
||||
void TermControl::_ApplyConnectionSettings()
|
||||
{
|
||||
_connection = TerminalConnection::ConhostConnection(_settings.Commandline(), _settings.StartingDirectory(), 30, 80, winrt::guid());
|
||||
}
|
||||
|
||||
TermControl::~TermControl()
|
||||
{
|
||||
Close();
|
||||
@@ -516,9 +548,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
_cursorTimer = std::nullopt;
|
||||
}
|
||||
|
||||
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
||||
_multiClickTimer = GetDoubleClickTime() * 1000;
|
||||
|
||||
_gotFocusRevoker = _controlRoot.GotFocus(winrt::auto_revoke, { this, &TermControl::_GotFocusHandler });
|
||||
_lostFocusRevoker = _controlRoot.LostFocus(winrt::auto_revoke, { this, &TermControl::_LostFocusHandler });
|
||||
|
||||
@@ -665,46 +694,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto modifiers = static_cast<uint32_t>(args.KeyModifiers());
|
||||
// static_cast to a uint32_t because we can't use the WI_IsFlagSet
|
||||
// macro directly with a VirtualKeyModifiers
|
||||
const auto altEnabled = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Menu));
|
||||
const auto shiftEnabled = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Shift));
|
||||
const auto modifiers = args.KeyModifiers();
|
||||
const auto altEnabled = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Menu);
|
||||
const auto shiftEnabled = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift);
|
||||
|
||||
if (point.Properties().IsLeftButtonPressed())
|
||||
{
|
||||
const auto cursorPosition = point.Position();
|
||||
const auto terminalPosition = _GetTerminalPosition(cursorPosition);
|
||||
|
||||
// save location before rendering
|
||||
_terminal->SetSelectionAnchor(terminalPosition);
|
||||
|
||||
// handle ALT key
|
||||
_terminal->SetBoxSelection(altEnabled);
|
||||
|
||||
auto clickCount = _NumberOfClicks(cursorPosition, point.Timestamp());
|
||||
|
||||
// This formula enables the number of clicks to cycle properly between single-, double-, and triple-click.
|
||||
// To increase the number of acceptable click states, simply increment MAX_CLICK_COUNT and add another if-statement
|
||||
const unsigned int MAX_CLICK_COUNT = 3;
|
||||
const auto multiClickMapper = clickCount > MAX_CLICK_COUNT ? ((clickCount + MAX_CLICK_COUNT - 1) % MAX_CLICK_COUNT) + 1 : clickCount;
|
||||
|
||||
if (multiClickMapper == 3)
|
||||
{
|
||||
_terminal->TripleClickSelection(terminalPosition);
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
else if (multiClickMapper == 2)
|
||||
{
|
||||
_terminal->DoubleClickSelection(terminalPosition);
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
// save location before rendering
|
||||
_terminal->SetSelectionAnchor(terminalPosition);
|
||||
|
||||
_renderer->TriggerSelection();
|
||||
_lastMouseClick = point.Timestamp();
|
||||
_lastMouseClickPos = cursorPosition;
|
||||
}
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
else if (point.Properties().IsRightButtonPressed())
|
||||
{
|
||||
@@ -716,7 +721,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// paste selection, otherwise
|
||||
else
|
||||
{
|
||||
PasteTextFromClipboard();
|
||||
// attach TermControl::_SendInputToConnection() as the clipboardDataHandler.
|
||||
// This is called when the clipboard data is loaded.
|
||||
auto clipboardDataHandler = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1);
|
||||
auto pasteArgs = winrt::make_self<PasteFromClipboardEventArgs>(clipboardDataHandler);
|
||||
|
||||
// send paste event up to TermApp
|
||||
_clipboardPasteHandlers(*this, *pasteArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -820,11 +831,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
auto delta = args.GetCurrentPoint(_root).Properties().MouseWheelDelta();
|
||||
// Get the state of the Ctrl & Shift keys
|
||||
// static_cast to a uint32_t because we can't use the WI_IsFlagSet macro
|
||||
// directly with a VirtualKeyModifiers
|
||||
const auto modifiers = static_cast<uint32_t>(args.KeyModifiers());
|
||||
const auto ctrlPressed = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Control));
|
||||
const auto shiftPressed = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Shift));
|
||||
const auto modifiers = args.KeyModifiers();
|
||||
const auto ctrlPressed = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Control);
|
||||
const auto shiftPressed = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift);
|
||||
|
||||
if (ctrlPressed && shiftPressed)
|
||||
{
|
||||
@@ -1088,10 +1097,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Process a resize event that was initiated by the user. This can either
|
||||
// be due to the user resizing the window (causing the swapchain to
|
||||
// resize) or due to the DPI changing (causing us to need to resize the
|
||||
// buffer to match)
|
||||
// - Process a resize event that was initiated by the user. This can either be due to the user resizing the window (causing the swapchain to resize) or due to the DPI changing (causing us to need to resize the buffer to match)
|
||||
// Arguments:
|
||||
// - newWidth: the new width of the swapchain, in pixels.
|
||||
// - newHeight: the new height of the swapchain, in pixels.
|
||||
@@ -1101,13 +1107,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
size.cx = static_cast<long>(newWidth);
|
||||
size.cy = static_cast<long>(newHeight);
|
||||
|
||||
// Don't actually resize so small that a single character wouldn't fit
|
||||
// in either dimension. The buffer really doesn't like being size 0.
|
||||
if (size.cx < _actualFont.GetSize().X || size.cy < _actualFont.GetSize().Y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell the dx engine that our window is now the new size.
|
||||
THROW_IF_FAILED(_renderEngine->SetWindowSize(size));
|
||||
|
||||
@@ -1210,19 +1209,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
_clipboardCopyHandlers(copiedData);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initiate a paste operation.
|
||||
void TermControl::PasteTextFromClipboard()
|
||||
{
|
||||
// attach TermControl::_SendInputToConnection() as the clipboardDataHandler.
|
||||
// This is called when the clipboard data is loaded.
|
||||
auto clipboardDataHandler = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1);
|
||||
auto pasteArgs = winrt::make_self<PasteFromClipboardEventArgs>(clipboardDataHandler);
|
||||
|
||||
// send paste event up to TermApp
|
||||
_clipboardPasteHandlers(*this, *pasteArgs);
|
||||
}
|
||||
|
||||
void TermControl::Close()
|
||||
{
|
||||
if (!_closing.exchange(true))
|
||||
@@ -1369,48 +1355,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the size of a single character of this control. The size is in
|
||||
// DIPs. If you need it in _pixels_, you'll need to multiply by the
|
||||
// current display scaling.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The dimensions of a single character of this control, in DIPs
|
||||
winrt::Windows::Foundation::Size TermControl::CharacterDimensions() const
|
||||
{
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
return { gsl::narrow_cast<float>(fontSize.X), gsl::narrow_cast<float>(fontSize.Y) };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the absolute minimum size that this control can be resized to and
|
||||
// still have 1x1 character visible. This includes the space needed for
|
||||
// the scrollbar and the padding.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The minimum size that this terminal control can be resized to and still
|
||||
// have a visible character.
|
||||
winrt::Windows::Foundation::Size TermControl::MinimumSize() const
|
||||
{
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
double width = fontSize.X;
|
||||
double height = fontSize.Y;
|
||||
// Reserve additional space if scrollbar is intended to be visible
|
||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
||||
{
|
||||
width += _scrollBar.ActualWidth();
|
||||
}
|
||||
|
||||
// Account for the size of any padding
|
||||
auto thickness = _ParseThicknessFromPadding(_settings.Padding());
|
||||
width += thickness.Left + thickness.Right;
|
||||
height += thickness.Top + thickness.Bottom;
|
||||
|
||||
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create XAML Thickness object based on padding props provided.
|
||||
// Used for controlling the TermControl XAML Grid container's Padding prop.
|
||||
@@ -1535,8 +1479,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
// Exclude padding from cursor position calculation
|
||||
COORD terminalPosition = {
|
||||
static_cast<SHORT>(cursorPosition.X - _swapChainPanel.Margin().Left),
|
||||
static_cast<SHORT>(cursorPosition.Y - _swapChainPanel.Margin().Top)
|
||||
static_cast<SHORT>(cursorPosition.X - _root.Padding().Left),
|
||||
static_cast<SHORT>(cursorPosition.Y - _root.Padding().Top)
|
||||
};
|
||||
|
||||
const auto fontSize = _actualFont.GetSize();
|
||||
@@ -1550,38 +1494,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
return terminalPosition;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the number of clicks that occurred (double and triple click support)
|
||||
// Arguments:
|
||||
// - clickPos: the (x,y) position of a given cursor (i.e.: mouse cursor).
|
||||
// NOTE: origin (0,0) is top-left.
|
||||
// - clickTime: the timestamp that the click occurred
|
||||
// Return Value:
|
||||
// - if the click is in the same position as the last click and within the timeout, the number of clicks within that time window
|
||||
// - otherwise, 1
|
||||
const unsigned int TermControl::_NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime)
|
||||
{
|
||||
// if click occurred at a different location or past the multiClickTimer...
|
||||
Timestamp delta;
|
||||
THROW_IF_FAILED(UInt64Sub(clickTime, _lastMouseClick, &delta));
|
||||
if (clickPos != _lastMouseClickPos || delta > _multiClickTimer)
|
||||
{
|
||||
// exit early. This is a single click.
|
||||
_multiClickCounter = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiClickCounter++;
|
||||
}
|
||||
return _multiClickCounter;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// Winrt events need a method for adding a callback to the event and removing the callback.
|
||||
// These macros will define them both for you.
|
||||
DEFINE_EVENT(TermControl, TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs);
|
||||
DEFINE_EVENT(TermControl, ConnectionClosed, _connectionClosedHandlers, TerminalControl::ConnectionClosedEventArgs);
|
||||
DEFINE_EVENT(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::CopyToClipboardEventArgs);
|
||||
DEFINE_EVENT(TermControl, TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs);
|
||||
DEFINE_EVENT(TermControl, ConnectionClosed, _connectionClosedHandlers, TerminalControl::ConnectionClosedEventArgs);
|
||||
DEFINE_EVENT(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::CopyToClipboardEventArgs);
|
||||
DEFINE_EVENT(TermControl, ScrollPositionChanged, _scrollPositionChangedHandlers, TerminalControl::ScrollPositionChangedEventArgs);
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
struct TermControl : TermControlT<TermControl>
|
||||
{
|
||||
TermControl();
|
||||
TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||
TermControl(Settings::IControlSettings settings);
|
||||
|
||||
Windows::UI::Xaml::UIElement GetRoot();
|
||||
Windows::UI::Xaml::Controls::UserControl GetControl();
|
||||
@@ -41,11 +41,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
|
||||
hstring Title();
|
||||
void CopySelectionToClipboard(bool trimTrailingWhitespace);
|
||||
void PasteTextFromClipboard();
|
||||
void Close();
|
||||
bool ShouldCloseOnExit() const noexcept;
|
||||
Windows::Foundation::Size CharacterDimensions() const;
|
||||
Windows::Foundation::Size MinimumSize() const;
|
||||
|
||||
void ScrollViewport(int viewTop);
|
||||
void KeyboardScrollViewport(int viewTop);
|
||||
@@ -73,7 +70,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
|
||||
Windows::UI::Xaml::Controls::UserControl _controlRoot;
|
||||
Windows::UI::Xaml::Controls::Grid _root;
|
||||
Windows::UI::Xaml::Controls::Image _bgImageLayer;
|
||||
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
|
||||
Windows::UI::Xaml::Controls::Primitives::ScrollBar _scrollBar;
|
||||
event_token _connectionOutputEventToken;
|
||||
@@ -101,15 +97,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
// viewport via touch input.
|
||||
std::optional<winrt::Windows::Foundation::Point> _touchAnchor;
|
||||
|
||||
using Timestamp = uint64_t;
|
||||
|
||||
// imported from WinUser
|
||||
// Used for PointerPoint.Timestamp Property (https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.pointerpoint.timestamp#Windows_UI_Input_PointerPoint_Timestamp)
|
||||
Timestamp _multiClickTimer;
|
||||
Timestamp _lastMouseClick;
|
||||
unsigned int _multiClickCounter;
|
||||
std::optional<winrt::Windows::Foundation::Point> _lastMouseClickPos;
|
||||
|
||||
// Event revokers -- we need to deregister ourselves before we die,
|
||||
// lest we get callbacks afterwards.
|
||||
winrt::Windows::UI::Xaml::Controls::Control::SizeChanged_revoker _sizeChangedRevoker;
|
||||
@@ -156,7 +143,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
DWORD _GetPressedModifierKeys() const;
|
||||
|
||||
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
|
||||
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Microsoft.Terminal.TerminalControl
|
||||
runtimeclass TermControl
|
||||
{
|
||||
TermControl();
|
||||
TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
TermControl(Microsoft.Terminal.Settings.IControlSettings settings);
|
||||
|
||||
static Windows.Foundation.Point GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi);
|
||||
|
||||
@@ -32,11 +32,8 @@ namespace Microsoft.Terminal.TerminalControl
|
||||
|
||||
String Title { get; };
|
||||
void CopySelectionToClipboard(Boolean trimTrailingWhitespace);
|
||||
void PasteTextFromClipboard();
|
||||
void Close();
|
||||
Boolean ShouldCloseOnExit { get; };
|
||||
Windows.Foundation.Size CharacterDimensions { get; };
|
||||
Windows.Foundation.Size MinimumSize { get; };
|
||||
|
||||
void ScrollViewport(Int32 viewTop);
|
||||
void KeyboardScrollViewport(Int32 viewTop);
|
||||
|
||||
@@ -44,15 +44,9 @@
|
||||
<ProjectReference Include="..\..\renderer\dx\lib\dx.vcxproj" />
|
||||
<ProjectReference Include="..\..\terminal\parser\lib\parser.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\terminal\input\lib\terminalinput.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj">
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalCore\lib\TerminalCore-lib.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" >
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -133,8 +133,6 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting
|
||||
|
||||
_snapOnInput = settings.SnapOnInput();
|
||||
|
||||
_wordDelimiters = settings.WordDelimiters();
|
||||
|
||||
// TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we
|
||||
// have a smaller scrollback. We should do this carefully - if the new buffer
|
||||
// size is smaller than where the mutable viewport currently is, we'll want
|
||||
|
||||
@@ -117,8 +117,6 @@ public:
|
||||
#pragma region TextSelection
|
||||
// These methods are defined in TerminalSelection.cpp
|
||||
const bool IsSelectionActive() const noexcept;
|
||||
void DoubleClickSelection(const COORD position);
|
||||
void TripleClickSelection(const COORD position);
|
||||
void SetSelectionAnchor(const COORD position);
|
||||
void SetEndSelectionPosition(const COORD position);
|
||||
void SetBoxSelection(const bool isEnabled) noexcept;
|
||||
@@ -151,7 +149,6 @@ private:
|
||||
bool _selectionActive;
|
||||
SHORT _selectionAnchor_YOffset;
|
||||
SHORT _endSelectionPosition_YOffset;
|
||||
std::wstring _wordDelimiters;
|
||||
|
||||
std::shared_mutex _readWriteLock;
|
||||
|
||||
@@ -194,9 +191,5 @@ private:
|
||||
std::vector<SMALL_RECT> _GetSelectionRects() const;
|
||||
const SHORT _ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const;
|
||||
const SHORT _ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const;
|
||||
void _ExpandDoubleClickSelectionLeft(const COORD position);
|
||||
void _ExpandDoubleClickSelectionRight(const COORD position);
|
||||
const bool _isWordDelimiter(std::wstring_view cellChar) const;
|
||||
const COORD _ConvertToBufferCell(const COORD viewportPos) const;
|
||||
#pragma endregion
|
||||
};
|
||||
|
||||
@@ -91,7 +91,7 @@ const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHOR
|
||||
{
|
||||
// move off by highlighting the lead half too.
|
||||
// alters position.X
|
||||
_buffer->GetSize().DecrementInBounds(position);
|
||||
_mutableViewport.DecrementInBounds(position);
|
||||
}
|
||||
return position.X;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHO
|
||||
{
|
||||
// move off by highlighting the trailing half too.
|
||||
// alters position.X
|
||||
_buffer->GetSize().IncrementInBounds(position);
|
||||
_mutableViewport.IncrementInBounds(position);
|
||||
}
|
||||
return position.X;
|
||||
}
|
||||
@@ -130,40 +130,6 @@ const bool Terminal::IsSelectionActive() const noexcept
|
||||
return _selectionActive;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Select the sequence between delimiters defined in Settings
|
||||
// Arguments:
|
||||
// - position: the (x,y) coordinate on the visible viewport
|
||||
void Terminal::DoubleClickSelection(const COORD position)
|
||||
{
|
||||
// if you double click a delimiter, just select that one cell
|
||||
COORD positionWithOffsets = _ConvertToBufferCell(position);
|
||||
const auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
|
||||
if (_isWordDelimiter(cellChar))
|
||||
{
|
||||
SetSelectionAnchor(position);
|
||||
return;
|
||||
}
|
||||
|
||||
// scan leftwards until delimiter is found and
|
||||
// set selection anchor to one right of that spot
|
||||
_ExpandDoubleClickSelectionLeft(position);
|
||||
|
||||
// scan rightwards until delimiter is found and
|
||||
// set endSelectionPosition to one left of that spot
|
||||
_ExpandDoubleClickSelectionRight(position);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Select the entire row of the position clicked
|
||||
// Arguments:
|
||||
// - position: the (x,y) coordinate on the visible viewport
|
||||
void Terminal::TripleClickSelection(const COORD position)
|
||||
{
|
||||
SetSelectionAnchor({ 0, position.Y });
|
||||
SetEndSelectionPosition({ _buffer->GetSize().RightInclusive(), position.Y });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Record the position of the beginning of a selection
|
||||
// Arguments:
|
||||
@@ -247,97 +213,3 @@ const std::wstring Terminal::RetrieveSelectedTextFromBuffer(bool trimTrailingWhi
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - expand the double click selection to the left (stopped by delimiter)
|
||||
// Arguments:
|
||||
// - position: viewport coordinate for selection
|
||||
// Return Value:
|
||||
// - update _selectionAnchor to new expanded location
|
||||
void Terminal::_ExpandDoubleClickSelectionLeft(const COORD position)
|
||||
{
|
||||
// don't change the value if at/outside the boundary
|
||||
if (position.X <= 0 || position.X >= _buffer->GetSize().RightInclusive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
COORD positionWithOffsets = _ConvertToBufferCell(position);
|
||||
const auto bufferViewport = _buffer->GetSize();
|
||||
auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
|
||||
while (positionWithOffsets.X != 0 && !_isWordDelimiter(cellChar))
|
||||
{
|
||||
bufferViewport.DecrementInBounds(positionWithOffsets);
|
||||
cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
|
||||
}
|
||||
|
||||
if (positionWithOffsets.X != 0 || _isWordDelimiter(cellChar))
|
||||
{
|
||||
// move off of delimiter to highlight properly
|
||||
bufferViewport.IncrementInBounds(positionWithOffsets);
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(ShortSub(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
|
||||
_selectionAnchor = positionWithOffsets;
|
||||
_selectionAnchor_YOffset = gsl::narrow<SHORT>(_ViewStartIndex());
|
||||
_selectionActive = true;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - expand the double click selection to the right (stopped by delimiter)
|
||||
// Arguments:
|
||||
// - position: viewport coordinate for selection
|
||||
// Return Value:
|
||||
// - update _endSelectionPosition to new expanded location
|
||||
void Terminal::_ExpandDoubleClickSelectionRight(const COORD position)
|
||||
{
|
||||
// don't change the value if at/outside the boundary
|
||||
if (position.X <= 0 || position.X >= _buffer->GetSize().RightInclusive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
COORD positionWithOffsets = _ConvertToBufferCell(position);
|
||||
const auto bufferViewport = _buffer->GetSize();
|
||||
auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
|
||||
while (positionWithOffsets.X != _buffer->GetSize().RightInclusive() && !_isWordDelimiter(cellChar))
|
||||
{
|
||||
bufferViewport.IncrementInBounds(positionWithOffsets);
|
||||
cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
|
||||
}
|
||||
|
||||
if (positionWithOffsets.X != bufferViewport.RightInclusive() || _isWordDelimiter(cellChar))
|
||||
{
|
||||
// move off of delimiter to highlight properly
|
||||
bufferViewport.DecrementInBounds(positionWithOffsets);
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(ShortSub(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
|
||||
_endSelectionPosition = positionWithOffsets;
|
||||
_endSelectionPosition_YOffset = gsl::narrow<SHORT>(_ViewStartIndex());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - check if buffer cell data contains delimiter for double click selection
|
||||
// Arguments:
|
||||
// - cellChar: the char saved to the buffer cell under observation
|
||||
// Return Value:
|
||||
// - true if cell data contains the delimiter.
|
||||
const bool Terminal::_isWordDelimiter(std::wstring_view cellChar) const
|
||||
{
|
||||
return _wordDelimiters.find(cellChar) != std::wstring_view::npos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - convert viewport position to the corresponding location on the buffer
|
||||
// Arguments:
|
||||
// - viewportPos: a coordinate on the viewport
|
||||
// Return Value:
|
||||
// - the corresponding location on the buffer
|
||||
const COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
|
||||
{
|
||||
COORD positionWithOffsets = viewportPos;
|
||||
THROW_IF_FAILED(ShortSub(viewportPos.Y, gsl::narrow<SHORT>(_scrollOffset), &positionWithOffsets.Y));
|
||||
THROW_IF_FAILED(ShortAdd(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
|
||||
return positionWithOffsets;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace Microsoft.Terminal.Settings
|
||||
UInt32 CursorColor;
|
||||
CursorStyle CursorShape;
|
||||
UInt32 CursorHeight;
|
||||
String WordDelimiters;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
||||
_cursorColor{ DEFAULT_CURSOR_COLOR },
|
||||
_cursorShape{ CursorStyle::Vintage },
|
||||
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },
|
||||
_wordDelimiters{ DEFAULT_WORD_DELIMITERS },
|
||||
_useAcrylic{ false },
|
||||
_closeOnExit{ true },
|
||||
_tintOpacity{ 0.5 },
|
||||
@@ -136,16 +135,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
||||
_cursorHeight = value;
|
||||
}
|
||||
|
||||
hstring TerminalSettings::WordDelimiters()
|
||||
{
|
||||
return _wordDelimiters;
|
||||
}
|
||||
|
||||
void TerminalSettings::WordDelimiters(hstring const& value)
|
||||
{
|
||||
_wordDelimiters = value;
|
||||
}
|
||||
|
||||
bool TerminalSettings::UseAcrylic()
|
||||
{
|
||||
return _useAcrylic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -45,8 +45,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
||||
void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept;
|
||||
uint32_t CursorHeight();
|
||||
void CursorHeight(uint32_t value);
|
||||
hstring WordDelimiters();
|
||||
void WordDelimiters(hstring const& value);
|
||||
// ------------------------ End of Core Settings -----------------------
|
||||
|
||||
bool UseAcrylic();
|
||||
@@ -96,7 +94,6 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
||||
uint32_t _cursorColor;
|
||||
Settings::CursorStyle _cursorShape;
|
||||
uint32_t _cursorHeight;
|
||||
hstring _wordDelimiters;
|
||||
|
||||
bool _useAcrylic;
|
||||
bool _closeOnExit;
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace TerminalCoreUnitTests
|
||||
uint32_t CursorColor() { return COLOR_WHITE; }
|
||||
CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; }
|
||||
uint32_t CursorHeight() { return 42UL; }
|
||||
winrt::hstring WordDelimiters() { return winrt::to_hstring(DEFAULT_WORD_DELIMITERS.c_str()); }
|
||||
|
||||
// other implemented methods
|
||||
uint32_t GetColorTableEntry(int32_t) const { return 123; }
|
||||
@@ -51,7 +50,6 @@ namespace TerminalCoreUnitTests
|
||||
void CursorColor(uint32_t) {}
|
||||
void CursorShape(CursorStyle const&) noexcept {}
|
||||
void CursorHeight(uint32_t) {}
|
||||
void WordDelimiters(winrt::hstring) {}
|
||||
|
||||
// other unimplemented methods
|
||||
void SetColorTableEntry(int32_t /* index */, uint32_t /* value */) {}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "pch.h"
|
||||
#include "AppHost.h"
|
||||
#include "../types/inc/Viewport.hpp"
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include "../types/inc/Utils.hpp"
|
||||
|
||||
using namespace winrt::Windows::UI;
|
||||
using namespace winrt::Windows::UI::Composition;
|
||||
@@ -14,6 +14,15 @@ using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
|
||||
// The tabs are 34.8px tall. This is their default height - we're not
|
||||
// controlling the styling of the tabs at all currently. If we change the size
|
||||
// of those, we'll need to change the size here, too. We can't get this size
|
||||
// from the tab control until the control is added to a XAML element, and we
|
||||
// can't create any XAML elements until we have a window, and we need to know
|
||||
// this size before we can create a window, so unfortunately we're stuck
|
||||
// hardcoding this.
|
||||
const int NON_CLIENT_CONTENT_HEIGHT = static_cast<int>(std::round(34.8));
|
||||
|
||||
AppHost::AppHost() noexcept :
|
||||
_app{},
|
||||
_window{ nullptr }
|
||||
@@ -23,6 +32,9 @@ AppHost::AppHost() noexcept :
|
||||
if (_useNonClientArea)
|
||||
{
|
||||
_window = std::make_unique<NonClientIslandWindow>();
|
||||
auto pNcWindow = static_cast<NonClientIslandWindow*>(_window.get());
|
||||
|
||||
pNcWindow->SetNonClientHeight(NON_CLIENT_CONTENT_HEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -41,10 +53,6 @@ AppHost::AppHost() noexcept :
|
||||
|
||||
AppHost::~AppHost()
|
||||
{
|
||||
// destruction order is important for proper teardown here
|
||||
_window = nullptr;
|
||||
_app.Close();
|
||||
_app = nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -61,25 +69,19 @@ AppHost::~AppHost()
|
||||
void AppHost::Initialize()
|
||||
{
|
||||
_window->Initialize();
|
||||
const auto handle = _window->GetHandle();
|
||||
_app.Create(reinterpret_cast<uint64_t>(handle));
|
||||
_app.Create();
|
||||
|
||||
_app.TitleChanged({ this, &AppHost::AppTitleChanged });
|
||||
_app.LastTabClosed({ this, &AppHost::LastTabClosed });
|
||||
|
||||
AppTitleChanged(_app.GetTitle());
|
||||
|
||||
_window->OnAppInitialized(_app);
|
||||
}
|
||||
|
||||
void AppHost::IncomingConnectionByHandle(HANDLE handle)
|
||||
{
|
||||
_app.IncomingConnection(reinterpret_cast<uint64_t>(handle));
|
||||
}
|
||||
|
||||
void AppHost::IncomingConnectionByLaunch(std::wstring_view cmdline, std::wstring_view workingDir)
|
||||
{
|
||||
_app.IncomingConnection(winrt::hstring(cmdline), winrt::hstring(workingDir));
|
||||
_window->SetRootContent(_app.GetRoot());
|
||||
if (_useNonClientArea)
|
||||
{
|
||||
auto pNcWindow = static_cast<NonClientIslandWindow*>(_window.get());
|
||||
pNcWindow->SetNonClientContent(_app.GetTabs());
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -14,8 +14,6 @@ public:
|
||||
AppHost() noexcept;
|
||||
virtual ~AppHost();
|
||||
|
||||
void IncomingConnectionByHandle(HANDLE handle);
|
||||
void IncomingConnectionByLaunch(std::wstring_view cmdline, std::wstring_view workingDir);
|
||||
void AppTitleChanged(winrt::hstring newTitle);
|
||||
void LastTabClosed();
|
||||
void Initialize();
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
// Custom window messages
|
||||
#define CM_UPDATE_TITLE (WM_USER)
|
||||
|
||||
#include <wil/resource.h>
|
||||
|
||||
template<typename T>
|
||||
class BaseWindow
|
||||
{
|
||||
@@ -28,7 +26,7 @@ public:
|
||||
T* that = static_cast<T*>(cs->lpCreateParams);
|
||||
WINRT_ASSERT(that);
|
||||
WINRT_ASSERT(!that->_window);
|
||||
that->_window = wil::unique_hwnd(window);
|
||||
that->_window = window;
|
||||
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(that));
|
||||
|
||||
EnableNonClientDpiScaling(window);
|
||||
@@ -48,7 +46,7 @@ public:
|
||||
{
|
||||
case WM_DPICHANGED:
|
||||
{
|
||||
return HandleDpiChange(_window.get(), wparam, lparam);
|
||||
return HandleDpiChange(_window, wparam, lparam);
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
@@ -89,16 +87,15 @@ public:
|
||||
// do nothing.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CM_UPDATE_TITLE:
|
||||
{
|
||||
SetWindowTextW(_window.get(), _title.c_str());
|
||||
SetWindowTextW(_window, _title.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(_window.get(), message, wparam, lparam);
|
||||
return DefWindowProc(_window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
// DPI Change handler. on WM_DPICHANGE resize the window
|
||||
@@ -128,18 +125,18 @@ public:
|
||||
RECT GetWindowRect() const noexcept
|
||||
{
|
||||
RECT rc = { 0 };
|
||||
::GetWindowRect(_window.get(), &rc);
|
||||
::GetWindowRect(_window, &rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
HWND GetHandle() const noexcept
|
||||
{
|
||||
return _window.get();
|
||||
return _window;
|
||||
};
|
||||
|
||||
float GetCurrentDpiScale() const noexcept
|
||||
{
|
||||
const auto dpi = ::GetDpiForWindow(_window.get());
|
||||
const auto dpi = ::GetDpiForWindow(_window);
|
||||
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
|
||||
return scale;
|
||||
}
|
||||
@@ -148,7 +145,7 @@ public:
|
||||
SIZE GetPhysicalSize() const noexcept
|
||||
{
|
||||
RECT rect = {};
|
||||
GetClientRect(_window.get(), &rect);
|
||||
GetClientRect(_window, &rect);
|
||||
const auto windowsWidth = rect.right - rect.left;
|
||||
const auto windowsHeight = rect.bottom - rect.top;
|
||||
return SIZE{ windowsWidth, windowsHeight };
|
||||
@@ -165,10 +162,10 @@ public:
|
||||
//// https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness
|
||||
winrt::Windows::Foundation::Size GetLogicalSize(const SIZE physicalSize) const noexcept
|
||||
{
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const auto dpi = GetCurrentDpiScale();
|
||||
// 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75
|
||||
const auto logicalWidth = (physicalSize.cx / scale) + 0.5f;
|
||||
const auto logicalHeigth = (physicalSize.cy / scale) + 0.5f;
|
||||
const auto logicalWidth = (physicalSize.cx / dpi) + 0.5f;
|
||||
const auto logicalHeigth = (physicalSize.cy / dpi) + 0.5f;
|
||||
return winrt::Windows::Foundation::Size(logicalWidth, logicalHeigth);
|
||||
}
|
||||
|
||||
@@ -186,12 +183,12 @@ public:
|
||||
void UpdateTitle(std::wstring_view newTitle)
|
||||
{
|
||||
_title = newTitle;
|
||||
PostMessageW(_window.get(), CM_UPDATE_TITLE, 0, reinterpret_cast<LPARAM>(nullptr));
|
||||
PostMessageW(_window, CM_UPDATE_TITLE, 0, reinterpret_cast<LPARAM>(nullptr));
|
||||
};
|
||||
|
||||
protected:
|
||||
using base_type = BaseWindow<T>;
|
||||
wil::unique_hwnd _window;
|
||||
HWND _window = nullptr;
|
||||
|
||||
unsigned int _currentDpi = 0;
|
||||
bool _inDpiChange = false;
|
||||
|
||||
@@ -27,7 +27,6 @@ IslandWindow::IslandWindow() noexcept :
|
||||
|
||||
IslandWindow::~IslandWindow()
|
||||
{
|
||||
_source.Close();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -79,7 +78,7 @@ void IslandWindow::Close()
|
||||
|
||||
// Method Description:
|
||||
// - Set a callback to be called when we process a WM_CREATE message. This gives
|
||||
// the AppHost a chance to resize the window to the proper size.
|
||||
// the AppHost a chance to resize the window to the propoer size.
|
||||
// Arguments:
|
||||
// - pfn: a function to be called during the handling of WM_CREATE. It takes two
|
||||
// parameters:
|
||||
@@ -112,11 +111,11 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
|
||||
|
||||
if (_pfnCreateCallback)
|
||||
{
|
||||
_pfnCreateCallback(_window.get(), rc);
|
||||
_pfnCreateCallback(_window, rc);
|
||||
}
|
||||
|
||||
ShowWindow(_window.get(), SW_SHOW);
|
||||
UpdateWindow(_window.get());
|
||||
ShowWindow(_window, SW_SHOW);
|
||||
UpdateWindow(_window);
|
||||
}
|
||||
|
||||
void IslandWindow::Initialize()
|
||||
@@ -126,19 +125,23 @@ void IslandWindow::Initialize()
|
||||
_source = DesktopWindowXamlSource{};
|
||||
|
||||
auto interop = _source.as<IDesktopWindowXamlSourceNative>();
|
||||
winrt::check_hresult(interop->AttachToWindow(_window.get()));
|
||||
winrt::check_hresult(interop->AttachToWindow(_window));
|
||||
|
||||
// stash the child interop handle so we can resize it when the main hwnd is resized
|
||||
interop->get_WindowHandle(&_interopWindowHandle);
|
||||
|
||||
_rootGrid = winrt::Windows::UI::Xaml::Controls::Grid();
|
||||
_source.Content(_rootGrid);
|
||||
|
||||
// Do a quick resize to force the island to paint
|
||||
OnSize();
|
||||
}
|
||||
|
||||
void IslandWindow::OnSize(const UINT width, const UINT height)
|
||||
void IslandWindow::OnSize()
|
||||
{
|
||||
const auto physicalSize = GetPhysicalSize();
|
||||
// update the interop window size
|
||||
SetWindowPos(_interopWindowHandle, 0, 0, 0, width, height, SWP_SHOWWINDOW);
|
||||
SetWindowPos(_interopWindowHandle, 0, 0, 0, physicalSize.cx, physicalSize.cy, SWP_SHOWWINDOW);
|
||||
|
||||
if (_rootGrid)
|
||||
{
|
||||
@@ -184,12 +187,9 @@ void IslandWindow::OnSize(const UINT width, const UINT height)
|
||||
// Arguments:
|
||||
// - width: the new width of the window _in pixels_
|
||||
// - height: the new height of the window _in pixels_
|
||||
void IslandWindow::OnResize(const UINT width, const UINT height)
|
||||
void IslandWindow::OnResize(const UINT /*width*/, const UINT /*height*/)
|
||||
{
|
||||
if (_interopWindowHandle)
|
||||
{
|
||||
OnSize(width, height);
|
||||
}
|
||||
OnSize();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -206,12 +206,8 @@ void IslandWindow::OnRestore()
|
||||
// TODO MSFT#21315817 Stop rendering island content when the app is minimized.
|
||||
}
|
||||
|
||||
void IslandWindow::OnAppInitialized(winrt::TerminalApp::App app)
|
||||
void IslandWindow::SetRootContent(winrt::Windows::UI::Xaml::UIElement content)
|
||||
{
|
||||
_rootGrid.Children().Clear();
|
||||
_rootGrid.Children().Append(app.GetRoot());
|
||||
|
||||
// Do a quick resize to force the island to paint
|
||||
const auto size = GetPhysicalSize();
|
||||
OnSize(size.cx, size.cy);
|
||||
_rootGrid.Children().Append(content);
|
||||
}
|
||||
|
||||
@@ -14,26 +14,19 @@ public:
|
||||
|
||||
void MakeWindow() noexcept;
|
||||
void Close();
|
||||
virtual void OnSize(const UINT width, const UINT height);
|
||||
virtual void OnSize();
|
||||
|
||||
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
|
||||
void OnResize(const UINT width, const UINT height) override;
|
||||
void OnMinimize() override;
|
||||
void OnRestore() override;
|
||||
virtual void OnAppInitialized(winrt::TerminalApp::App app);
|
||||
void SetRootContent(winrt::Windows::UI::Xaml::UIElement content);
|
||||
|
||||
void Initialize();
|
||||
virtual void Initialize();
|
||||
|
||||
void SetCreateCallback(std::function<void(const HWND, const RECT)> pfn) noexcept;
|
||||
|
||||
protected:
|
||||
void ForceResize()
|
||||
{
|
||||
// Do a quick resize to force the island to paint
|
||||
const auto size = GetPhysicalSize();
|
||||
OnSize(size.cx, size.cy);
|
||||
}
|
||||
|
||||
HWND _interopWindowHandle;
|
||||
|
||||
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source;
|
||||
|
||||
@@ -26,6 +26,10 @@ constexpr int RECT_HEIGHT(const RECT* const pRect)
|
||||
|
||||
NonClientIslandWindow::NonClientIslandWindow() noexcept :
|
||||
IslandWindow{},
|
||||
_nonClientInteropWindowHandle{ nullptr },
|
||||
_nonClientRootGrid{ nullptr },
|
||||
_nonClientSource{ nullptr },
|
||||
_maximizedMargins{ 0 },
|
||||
_isMaximized{ false }
|
||||
{
|
||||
}
|
||||
@@ -35,149 +39,161 @@ NonClientIslandWindow::~NonClientIslandWindow()
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when the app's size changes. When that happens, the size of the drag
|
||||
// bar may have changed. If it has, we'll need to update the WindowRgn of the
|
||||
// interop window.
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void NonClientIslandWindow::OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable /*sender*/, winrt::Windows::UI::Xaml::SizeChangedEventArgs /*eventArgs*/)
|
||||
// - Used to initialize the XAML island for the non-client area. Also calls our
|
||||
// base IslandWindow's Initialize, which will initialize the client XAML
|
||||
// Island.
|
||||
void NonClientIslandWindow::Initialize()
|
||||
{
|
||||
_UpdateDragRegion();
|
||||
}
|
||||
_nonClientSource = DesktopWindowXamlSource{};
|
||||
auto interop = _nonClientSource.as<IDesktopWindowXamlSourceNative>();
|
||||
winrt::check_hresult(interop->AttachToWindow(_window));
|
||||
|
||||
void NonClientIslandWindow::OnAppInitialized(winrt::TerminalApp::App app)
|
||||
{
|
||||
_dragBar = app.GetDragBar();
|
||||
_rootGrid.SizeChanged({ this, &NonClientIslandWindow::OnDragBarSizeChanged });
|
||||
// stash the child interop handle so we can resize it when the main hwnd is resized
|
||||
interop->get_WindowHandle(&_nonClientInteropWindowHandle);
|
||||
|
||||
IslandWindow::OnAppInitialized(app);
|
||||
}
|
||||
_nonClientRootGrid = winrt::Windows::UI::Xaml::Controls::Grid{};
|
||||
|
||||
RECT NonClientIslandWindow::GetDragAreaRect() const noexcept
|
||||
{
|
||||
if (_dragBar)
|
||||
{
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const auto transform = _dragBar.TransformToVisual(_rootGrid);
|
||||
const auto logicalDragBarRect = winrt::Windows::Foundation::Rect{ 0.0f, 0.0f, static_cast<float>(_dragBar.ActualWidth()), static_cast<float>(_dragBar.ActualHeight()) };
|
||||
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
|
||||
RECT dragBarRect = {
|
||||
static_cast<LONG>(clientDragBarRect.X * scale),
|
||||
static_cast<LONG>(clientDragBarRect.Y * scale),
|
||||
static_cast<LONG>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
|
||||
static_cast<LONG>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
|
||||
};
|
||||
return dragBarRect;
|
||||
}
|
||||
_nonClientSource.Content(_nonClientRootGrid);
|
||||
|
||||
return RECT{};
|
||||
// Call the IslandWindow Initialize to set up the client xaml island
|
||||
IslandWindow::Initialize();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - called when the size of the window changes for any reason. Updates the
|
||||
// sizes of our child Xaml Islands to match our new sizing.
|
||||
void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
|
||||
// - Sets the content of the non-client area of our window to the given XAML element.
|
||||
// Arguments:
|
||||
// - content: a XAML element to use as the content of the titlebar.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void NonClientIslandWindow::SetNonClientContent(winrt::Windows::UI::Xaml::UIElement content)
|
||||
{
|
||||
if (!_interopWindowHandle)
|
||||
_nonClientRootGrid.Children().Clear();
|
||||
_nonClientRootGrid.Children().Append(content);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Set the height we expect to reserve for the non-client content.
|
||||
// Arguments:
|
||||
// - contentHeight: the size in pixels we should use for the non-client content.
|
||||
void NonClientIslandWindow::SetNonClientHeight(const int contentHeight) noexcept
|
||||
{
|
||||
_titlebarUnscaledContentHeight = contentHeight;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the size of the content area of the titlebar (the non-client area).
|
||||
// This can be padded either by the margins from maximization (when the window
|
||||
// is maximized) or the normal window borders.
|
||||
// Return Value:
|
||||
// - A Viewport representing the area of the window which should be the titlebar
|
||||
// content, in window coordinates.
|
||||
Viewport NonClientIslandWindow::GetTitlebarContentArea() const noexcept
|
||||
{
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
|
||||
const auto titlebarContentHeight = _titlebarUnscaledContentHeight * scale;
|
||||
const auto titlebarMarginRight = _titlebarMarginRight;
|
||||
|
||||
const auto physicalSize = GetPhysicalSize();
|
||||
const auto clientWidth = physicalSize.cx;
|
||||
|
||||
auto titlebarWidth = clientWidth - (_windowMarginSides + titlebarMarginRight);
|
||||
// Adjust for maximized margins
|
||||
titlebarWidth -= (_maximizedMargins.cxLeftWidth + _maximizedMargins.cxRightWidth);
|
||||
|
||||
const auto titlebarHeight = titlebarContentHeight - (_titlebarMarginTop + _titlebarMarginBottom);
|
||||
|
||||
COORD titlebarOrigin = { static_cast<short>(_windowMarginSides),
|
||||
static_cast<short>(_titlebarMarginTop) };
|
||||
|
||||
if (_isMaximized)
|
||||
{
|
||||
return;
|
||||
titlebarOrigin.X = static_cast<short>(_maximizedMargins.cxLeftWidth);
|
||||
titlebarOrigin.Y = static_cast<short>(_maximizedMargins.cyTopHeight);
|
||||
}
|
||||
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const auto dpi = ::GetDpiForWindow(_window.get());
|
||||
return Viewport::FromDimensions(titlebarOrigin,
|
||||
{ static_cast<short>(titlebarWidth), static_cast<short>(titlebarHeight) });
|
||||
}
|
||||
|
||||
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
|
||||
const auto dragX = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
|
||||
// Method Description:
|
||||
// - Gets the size of the client content area of the window.
|
||||
// This can be padded either by the margins from maximization (when the window
|
||||
// is maximized) or the normal window borders.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - A Viewport representing the area of the window which should be the client
|
||||
// content, in window coordinates.
|
||||
Viewport NonClientIslandWindow::GetClientContentArea() const noexcept
|
||||
{
|
||||
MARGINS margins = GetFrameMargins();
|
||||
|
||||
COORD clientOrigin = { static_cast<short>(margins.cxLeftWidth),
|
||||
static_cast<short>(margins.cyTopHeight) };
|
||||
|
||||
const auto physicalSize = GetPhysicalSize();
|
||||
auto clientWidth = physicalSize.cx;
|
||||
auto clientHeight = physicalSize.cy;
|
||||
|
||||
// If we're maximized, we don't want to use the frame as our margins,
|
||||
// instead we want to use the margins from the maximization. If we included
|
||||
// the left&right sides of the frame in this calculation while maximized,
|
||||
// you' have a few pixels of the window border on the sides while maximized,
|
||||
// which most apps do not have.
|
||||
const auto bordersWidth = _isMaximized ?
|
||||
(_maximizedMargins.cxLeftWidth + _maximizedMargins.cxRightWidth) :
|
||||
(dragX * 2);
|
||||
const auto bordersHeight = _isMaximized ?
|
||||
(_maximizedMargins.cyBottomHeight + _maximizedMargins.cyTopHeight) :
|
||||
(dragY * 2);
|
||||
|
||||
const auto windowsWidth = width - bordersWidth;
|
||||
const auto windowsHeight = height - bordersHeight;
|
||||
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
|
||||
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
|
||||
|
||||
if (_rootGrid)
|
||||
if (_isMaximized)
|
||||
{
|
||||
winrt::Windows::Foundation::Size size{ (windowsWidth / scale) + 0.5f, (windowsHeight / scale) + 0.5f };
|
||||
_rootGrid.Height(size.Height);
|
||||
_rootGrid.Width(size.Width);
|
||||
_rootGrid.Measure(size);
|
||||
winrt::Windows::Foundation::Rect finalRect{};
|
||||
_rootGrid.Arrange(finalRect);
|
||||
clientWidth -= (_maximizedMargins.cxLeftWidth + _maximizedMargins.cxRightWidth);
|
||||
clientHeight -= (margins.cyTopHeight + _maximizedMargins.cyBottomHeight);
|
||||
clientOrigin.X = static_cast<short>(_maximizedMargins.cxLeftWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the left and right width of the frame from the client area
|
||||
clientWidth -= (margins.cxLeftWidth + margins.cxRightWidth);
|
||||
clientHeight -= (margins.cyTopHeight + margins.cyBottomHeight);
|
||||
}
|
||||
|
||||
// I'm not sure that HWND_BOTTOM is any different than HWND_TOP for us.
|
||||
winrt::check_bool(SetWindowPos(_interopWindowHandle, HWND_BOTTOM, xPos, yPos, windowsWidth, windowsHeight, SWP_SHOWWINDOW));
|
||||
// The top maximization margin is already included in the GetFrameMargins
|
||||
// calcualtion.
|
||||
|
||||
return Viewport::FromDimensions(clientOrigin,
|
||||
{ static_cast<short>(clientWidth), static_cast<short>(clientHeight) });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the region of our window that is the draggable area. This happens in
|
||||
// response to a OnDragBarSizeChanged event. We'll calculate the areas of the
|
||||
// window that we want to display XAML content in, and set the window region
|
||||
// of our child xaml-island window to that region. That way, the parent window
|
||||
// will still get NCHITTEST'ed _outside_ the XAML content area, for things
|
||||
// like dragging and resizing.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void NonClientIslandWindow::_UpdateDragRegion()
|
||||
// - called when the size of the window changes for any reason. Updates the
|
||||
// sizes of our child Xaml Islands to match our new sizing.
|
||||
void NonClientIslandWindow::OnSize()
|
||||
{
|
||||
if (_dragBar)
|
||||
auto clientArea = GetClientContentArea();
|
||||
auto titlebarArea = GetTitlebarContentArea();
|
||||
|
||||
// update the interop window size
|
||||
SetWindowPos(_interopWindowHandle,
|
||||
0,
|
||||
clientArea.Left(),
|
||||
clientArea.Top(),
|
||||
clientArea.Width(),
|
||||
clientArea.Height(),
|
||||
SWP_SHOWWINDOW);
|
||||
|
||||
if (_rootGrid)
|
||||
{
|
||||
// TODO:GH#1897 This is largely duplicated from OnSize, and we should do
|
||||
// better than that.
|
||||
const auto windowRect = GetWindowRect();
|
||||
const auto width = windowRect.right - windowRect.left;
|
||||
const auto height = windowRect.bottom - windowRect.top;
|
||||
|
||||
const auto dpi = ::GetDpiForWindow(_window.get());
|
||||
|
||||
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
|
||||
const auto dragX = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
|
||||
|
||||
// If we're maximized, we don't want to use the frame as our margins,
|
||||
// instead we want to use the margins from the maximization. If we included
|
||||
// the left&right sides of the frame in this calculation while maximized,
|
||||
// you' have a few pixels of the window border on the sides while maximized,
|
||||
// which most apps do not have.
|
||||
const auto bordersWidth = _isMaximized ?
|
||||
(_maximizedMargins.cxLeftWidth + _maximizedMargins.cxRightWidth) :
|
||||
(dragX * 2);
|
||||
const auto bordersHeight = _isMaximized ?
|
||||
(_maximizedMargins.cyBottomHeight + _maximizedMargins.cyTopHeight) :
|
||||
(dragY * 2);
|
||||
|
||||
const auto windowsWidth = width - bordersWidth;
|
||||
const auto windowsHeight = height - bordersHeight;
|
||||
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
|
||||
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
|
||||
|
||||
const auto dragBarRect = GetDragAreaRect();
|
||||
const auto nonClientHeight = dragBarRect.bottom - dragBarRect.top;
|
||||
|
||||
auto nonClientRegion = wil::unique_hrgn(CreateRectRgn(0, 0, 0, 0));
|
||||
auto nonClientLeftRegion = wil::unique_hrgn(CreateRectRgn(0, 0, dragBarRect.left, nonClientHeight));
|
||||
auto nonClientRightRegion = wil::unique_hrgn(CreateRectRgn(dragBarRect.right, 0, windowsWidth, nonClientHeight));
|
||||
winrt::check_bool(CombineRgn(nonClientRegion.get(), nonClientLeftRegion.get(), nonClientRightRegion.get(), RGN_OR));
|
||||
|
||||
_dragBarRegion = wil::unique_hrgn(CreateRectRgn(0, 0, 0, 0));
|
||||
auto clientRegion = wil::unique_hrgn(CreateRectRgn(0, nonClientHeight, windowsWidth, windowsHeight));
|
||||
winrt::check_bool(CombineRgn(_dragBarRegion.get(), nonClientRegion.get(), clientRegion.get(), RGN_OR));
|
||||
winrt::check_bool(SetWindowRgn(_interopWindowHandle, _dragBarRegion.get(), true));
|
||||
const SIZE physicalSize{ clientArea.Width(), clientArea.Height() };
|
||||
const auto logicalSize = GetLogicalSize(physicalSize);
|
||||
_rootGrid.Width(logicalSize.Width);
|
||||
_rootGrid.Height(logicalSize.Height);
|
||||
}
|
||||
|
||||
// update the interop window size
|
||||
SetWindowPos(_nonClientInteropWindowHandle,
|
||||
0,
|
||||
titlebarArea.Left(),
|
||||
titlebarArea.Top(),
|
||||
titlebarArea.Width(),
|
||||
titlebarArea.Height(),
|
||||
SWP_SHOWWINDOW);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -252,19 +268,13 @@ void NonClientIslandWindow::_UpdateDragRegion()
|
||||
// - A MARGINS struct containing the border dimensions we want.
|
||||
MARGINS NonClientIslandWindow::GetFrameMargins() const noexcept
|
||||
{
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const auto dpi = ::GetDpiForWindow(_window.get());
|
||||
const auto windowMarginSides = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
|
||||
const auto windowMarginBottom = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
|
||||
|
||||
const auto dragBarRect = GetDragAreaRect();
|
||||
const auto nonClientHeight = dragBarRect.bottom - dragBarRect.top;
|
||||
const auto titlebarView = GetTitlebarContentArea();
|
||||
|
||||
MARGINS margins{ 0 };
|
||||
margins.cxLeftWidth = windowMarginSides;
|
||||
margins.cxRightWidth = windowMarginSides;
|
||||
margins.cyBottomHeight = windowMarginBottom;
|
||||
margins.cyTopHeight = nonClientHeight + windowMarginBottom;
|
||||
margins.cxLeftWidth = _windowMarginSides;
|
||||
margins.cxRightWidth = _windowMarginSides;
|
||||
margins.cyBottomHeight = _windowMarginBottom;
|
||||
margins.cyTopHeight = titlebarView.BottomExclusive();
|
||||
|
||||
return margins;
|
||||
}
|
||||
@@ -277,15 +287,12 @@ MARGINS NonClientIslandWindow::GetFrameMargins() const noexcept
|
||||
// - the HRESULT returned by DwmExtendFrameIntoClientArea.
|
||||
[[nodiscard]] HRESULT NonClientIslandWindow::_UpdateFrameMargins() const noexcept
|
||||
{
|
||||
// Set frame margins with just a single pixel on the bottom. We don't
|
||||
// really want a window frame at all - we're drawing all of it. We
|
||||
// especially don't want a top margin - that's where the caption buttons
|
||||
// are, and we're drawing those. So just set a single pixel on the bottom,
|
||||
// because the method won't work with {0}.
|
||||
MARGINS margins = { 0, 0, 0, 1 };
|
||||
|
||||
// Get the size of the borders we want to use. The sides and bottom will
|
||||
// just be big enough for resizing, but the top will be as big as we need
|
||||
// for the non-client content.
|
||||
MARGINS margins = GetFrameMargins();
|
||||
// Extend the frame into the client area.
|
||||
return DwmExtendFrameIntoClientArea(_window.get(), &margins);
|
||||
return DwmExtendFrameIntoClientArea(_window, &margins);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -306,7 +313,8 @@ MARGINS NonClientIslandWindow::GetFrameMargins() const noexcept
|
||||
// origin in pixels. Measures the outer edges of the potential window.
|
||||
// NOTE:
|
||||
// Heavily taken from WindowMetrics::GetMaxWindowRectInPixels in conhost.
|
||||
RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Out_opt_ UINT* pDpiSuggested)
|
||||
RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSuggested,
|
||||
_Out_opt_ UINT* pDpiSuggested)
|
||||
{
|
||||
// prepare rectangle
|
||||
RECT rc = *prcSuggested;
|
||||
@@ -328,7 +336,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
else
|
||||
{
|
||||
// Otherwise, get the monitor from the window handle.
|
||||
hMonitor = MonitorFromWindow(_window.get(), MONITOR_DEFAULTTONEAREST);
|
||||
hMonitor = MonitorFromWindow(_window, MONITOR_DEFAULTTONEAREST);
|
||||
}
|
||||
|
||||
// If for whatever reason there is no monitor, we're going to give back whatever we got since we can't figure anything out.
|
||||
@@ -349,7 +357,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
// We need to pad the work rectangle with the border dimensions to represent the actual max outer edges of the window rect.
|
||||
WINDOWINFO wi = { 0 };
|
||||
wi.cbSize = sizeof(WINDOWINFO);
|
||||
GetWindowInfo(_window.get(), &wi);
|
||||
GetWindowInfo(_window, &wi);
|
||||
|
||||
// In non-full screen, we want to only use the work area (avoiding the task bar space)
|
||||
rc = MonitorInfo.rcWork;
|
||||
@@ -364,7 +372,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
}
|
||||
else
|
||||
{
|
||||
*pDpiSuggested = GetDpiForWindow(_window.get());
|
||||
*pDpiSuggested = GetDpiForWindow(_window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +396,7 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
|
||||
// First call DwmDefWindowProc. This might handle things like the
|
||||
// min/max/close buttons for us.
|
||||
const bool dwmHandledMessage = DwmDefWindowProc(_window.get(), message, wParam, lParam, &lRet);
|
||||
const bool dwmHandledMessage = DwmDefWindowProc(_window, message, wParam, lParam, &lRet);
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -437,86 +445,6 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_EXITSIZEMOVE:
|
||||
{
|
||||
ForceResize();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
if (!_dragBar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PAINTSTRUCT ps{ 0 };
|
||||
const auto hdc = wil::BeginPaint(_window.get(), &ps);
|
||||
if (hdc.get())
|
||||
{
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const auto dpi = ::GetDpiForWindow(_window.get());
|
||||
// Get the dimensions of the drag borders for the sides of the window.
|
||||
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
|
||||
const auto dragX = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
|
||||
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
|
||||
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
|
||||
|
||||
// Create brush for borders, titlebar color.
|
||||
const auto backgroundBrush = _dragBar.Background();
|
||||
const auto backgroundSolidBrush = backgroundBrush.as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
|
||||
const auto backgroundColor = backgroundSolidBrush.Color();
|
||||
const auto color = RGB(backgroundColor.R, backgroundColor.G, backgroundColor.B);
|
||||
_backgroundBrush = wil::unique_hbrush(CreateSolidBrush(color));
|
||||
|
||||
RECT windowRect = {};
|
||||
::GetWindowRect(_window.get(), &windowRect);
|
||||
const auto cx = windowRect.right - windowRect.left;
|
||||
const auto cy = windowRect.bottom - windowRect.top;
|
||||
|
||||
// Fill in the _entire_ titlebar area.
|
||||
RECT dragBarRect = {};
|
||||
dragBarRect.left = xPos;
|
||||
dragBarRect.right = xPos + cx;
|
||||
dragBarRect.top = yPos;
|
||||
dragBarRect.bottom = yPos + cy;
|
||||
::FillRect(hdc.get(), &dragBarRect, _backgroundBrush.get());
|
||||
|
||||
// Draw the top window border
|
||||
RECT clientRect = { 0, 0, cx, yPos };
|
||||
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
|
||||
|
||||
// Draw the left window border
|
||||
clientRect = { 0, 0, xPos, cy };
|
||||
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
|
||||
|
||||
// Draw the bottom window border
|
||||
clientRect = { 0, cy - yPos, cx, cy };
|
||||
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
|
||||
|
||||
// Draw the right window border
|
||||
clientRect = { cx - xPos, 0, cx, cy };
|
||||
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
POINT point1 = {};
|
||||
::GetCursorPos(&point1);
|
||||
const auto region = HitTestNCA(point1);
|
||||
if (region == HTCAPTION)
|
||||
{
|
||||
const auto longParam = MAKELPARAM(point1.x, point1.y);
|
||||
::SetActiveWindow(_window.get());
|
||||
::PostMessage(_window.get(), WM_SYSCOMMAND, SC_MOVE | HTCAPTION, longParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
{
|
||||
// Enforce maximum size here instead of WM_GETMINMAXINFO. If we return
|
||||
@@ -548,6 +476,19 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
|
||||
// non-client area of the window.
|
||||
void NonClientIslandWindow::_HandleActivateWindow()
|
||||
{
|
||||
const auto dpi = GetDpiForWindow(_window);
|
||||
|
||||
// Use DwmGetWindowAttribute to get the complete size of the caption buttons.
|
||||
RECT captionSize{ 0 };
|
||||
THROW_IF_FAILED(DwmGetWindowAttribute(_window, DWMWA_CAPTION_BUTTON_BOUNDS, &captionSize, sizeof(RECT)));
|
||||
|
||||
// Divide by 3 to get the width of a single button
|
||||
// Multiply by 4 to reserve the space of one button as the "grab handle"
|
||||
_titlebarMarginRight = MulDiv(RECT_WIDTH(&captionSize), 4, 3);
|
||||
|
||||
// _titlebarUnscaledContentHeight is set with SetNonClientHeight by the app
|
||||
// hosting us.
|
||||
|
||||
THROW_IF_FAILED(_UpdateFrameMargins());
|
||||
}
|
||||
|
||||
@@ -620,7 +561,7 @@ bool NonClientIslandWindow::_HandleWindowPosChanging(WINDOWPOS* const windowPos)
|
||||
}
|
||||
}
|
||||
|
||||
const auto windowStyle = GetWindowStyle(_window.get());
|
||||
const auto windowStyle = GetWindowStyle(_window);
|
||||
const auto isMaximized = WI_IsFlagSet(windowStyle, WS_MAXIMIZE);
|
||||
|
||||
// If we're about to maximize the window, determine how much we're about to
|
||||
@@ -669,19 +610,27 @@ bool NonClientIslandWindow::_HandleWindowPosChanging(WINDOWPOS* const windowPos)
|
||||
((suggestedWidth > maxWidth) ||
|
||||
(suggestedHeight > maxHeight)))
|
||||
{
|
||||
RECT frame{};
|
||||
// Calculate the maxmized window overhang by getting the size of the window frame.
|
||||
// We use the style without WS_CAPTION otherwise the caption height is included.
|
||||
// Only remove WS_DLGFRAME since WS_CAPTION = WS_DLGFRAME | WS_BORDER,
|
||||
// but WS_BORDER is needed as it modifies the calculation of the width of the frame.
|
||||
const auto targetStyle = windowStyle & ~WS_DLGFRAME;
|
||||
AdjustWindowRectExForDpi(&frame, targetStyle, false, GetWindowExStyle(_window.get()), _currentDpi);
|
||||
auto offset = 0;
|
||||
// Determine which side of the window to use for the offset
|
||||
// calculation. If the taskbar is on the left or top of the screen,
|
||||
// then the x or y coordinate of the work rect might not be 0.
|
||||
// Check both, and use whichever is 0.
|
||||
if (rcMaximum.left == 0)
|
||||
{
|
||||
offset = windowPos->x;
|
||||
}
|
||||
else if (rcMaximum.top == 0)
|
||||
{
|
||||
offset = windowPos->y;
|
||||
}
|
||||
const auto offsetX = offset;
|
||||
const auto offsetY = offset;
|
||||
|
||||
// Frame left and top will be negative
|
||||
_maximizedMargins.cxLeftWidth = frame.left * -1;
|
||||
_maximizedMargins.cyTopHeight = frame.top * -1;
|
||||
_maximizedMargins.cxRightWidth = frame.right;
|
||||
_maximizedMargins.cyBottomHeight = frame.bottom;
|
||||
_maximizedMargins.cxRightWidth = -offset;
|
||||
_maximizedMargins.cxLeftWidth = -offset;
|
||||
|
||||
_maximizedMargins.cyTopHeight = -offset;
|
||||
_maximizedMargins.cyBottomHeight = -offset;
|
||||
|
||||
_isMaximized = true;
|
||||
THROW_IF_FAILED(_UpdateFrameMargins());
|
||||
|
||||
@@ -22,7 +22,6 @@ Author(s):
|
||||
#include "../../types/inc/Viewport.hpp"
|
||||
#include <dwmapi.h>
|
||||
#include <windowsx.h>
|
||||
#include <wil\resource.h>
|
||||
|
||||
class NonClientIslandWindow : public IslandWindow
|
||||
{
|
||||
@@ -30,23 +29,37 @@ public:
|
||||
NonClientIslandWindow() noexcept;
|
||||
virtual ~NonClientIslandWindow() override;
|
||||
|
||||
virtual void OnSize(const UINT width, const UINT height) override;
|
||||
virtual void OnSize() override;
|
||||
|
||||
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
|
||||
|
||||
void SetNonClientContent(winrt::Windows::UI::Xaml::UIElement content);
|
||||
|
||||
virtual void Initialize() override;
|
||||
|
||||
MARGINS GetFrameMargins() const noexcept;
|
||||
|
||||
void OnAppInitialized(winrt::TerminalApp::App app) override;
|
||||
void SetNonClientHeight(const int contentHeight) noexcept;
|
||||
|
||||
private:
|
||||
wil::unique_hbrush _backgroundBrush;
|
||||
wil::unique_hrgn _dragBarRegion;
|
||||
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _nonClientSource;
|
||||
|
||||
MARGINS _maximizedMargins = { 0 };
|
||||
HWND _nonClientInteropWindowHandle;
|
||||
winrt::Windows::UI::Xaml::Controls::Grid _nonClientRootGrid;
|
||||
|
||||
int _windowMarginBottom = 2;
|
||||
int _windowMarginSides = 2;
|
||||
int _titlebarMarginRight = 0;
|
||||
int _titlebarMarginTop = 2;
|
||||
int _titlebarMarginBottom = 0;
|
||||
|
||||
int _titlebarUnscaledContentHeight = 0;
|
||||
|
||||
::Microsoft::Console::Types::Viewport GetTitlebarContentArea() const noexcept;
|
||||
::Microsoft::Console::Types::Viewport GetClientContentArea() const noexcept;
|
||||
|
||||
MARGINS _maximizedMargins;
|
||||
bool _isMaximized;
|
||||
winrt::Windows::UI::Xaml::Controls::Border _dragBar{ nullptr };
|
||||
|
||||
RECT GetDragAreaRect() const noexcept;
|
||||
|
||||
[[nodiscard]] LRESULT HitTestNCA(POINT ptMouse) const noexcept;
|
||||
|
||||
@@ -54,9 +67,6 @@ private:
|
||||
|
||||
void _HandleActivateWindow();
|
||||
bool _HandleWindowPosChanging(WINDOWPOS* const windowPos);
|
||||
void _UpdateDragRegion();
|
||||
|
||||
void OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs eventArgs);
|
||||
|
||||
RECT GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Out_opt_ UINT* pDpiSuggested);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
|
||||
<!-- This file is copied into ut_app/TerminalApp.Unit.Tests.manifest as part
|
||||
of the pre-build step for that project. Changes should only be made to the
|
||||
WindowsTerminal version of the file. -->
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 1903 -->
|
||||
@@ -27,7 +22,7 @@
|
||||
Whenever you add new cppwinrt classes, make sure to add them here.
|
||||
If you need help with the syntax, the generated AppxManifest.xml should have
|
||||
the classes and files all listed in it.
|
||||
|
||||
|
||||
TODO MSFT#21300206: Switch to automatically generating these.
|
||||
-->
|
||||
<file name="TerminalSettings.dll" hashalg="SHA1">
|
||||
@@ -135,7 +130,7 @@
|
||||
<activatableClass name="Microsoft.UI.Xaml.Media.RevealBorderBrush" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
<activatableClass name="Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
</file>
|
||||
<file name="Microsoft.Toolkit.Win32.UI.XamlHost.dll" hashalg="SHA1">
|
||||
<activatableClass name="Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
<file name="Microsoft.UI.Xaml.Markup.dll" hashalg="SHA1">
|
||||
<activatableClass name="Microsoft.UI.Xaml.Markup.XamlApplication" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
|
||||
</file>
|
||||
</assembly>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -25,18 +24,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
@@ -45,36 +44,11 @@ END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_ERROR_DIALOG_TITLE "Error"
|
||||
IDS_ERROR_ARCHITECTURE_FORMAT
|
||||
"Windows Terminal is designed to run on your system's native architecture (%s).\nYou are currently using the %s version.\n\nPlease use the version of Windows Terminal that matches your system's native architecture."
|
||||
IDS_X86_ARCHITECTURE "i386"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_AMD64_ARCHITECTURE "AMD64"
|
||||
IDS_ARM64_ARCHITECTURE "ARM64"
|
||||
IDS_ARM_ARCHITECTURE "ARM"
|
||||
IDS_UNKNOWN_ARCHITECTURE "Unknown"
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -91,3 +65,4 @@ END
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -18,7 +17,7 @@
|
||||
<TargetName>WindowsTerminal</TargetName>
|
||||
<!-- IMPORTANT! Xaml Islands only works on >= 17709 -->
|
||||
<!-- IMPORTANT! cppwinrt.pre.props specifies 17134 -->
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
@@ -36,7 +35,7 @@
|
||||
<AdditionalIncludeDirectories>"$(OpenConsoleDir)src\cascadia\TerminalCore\lib\Generated Files";%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>gdi32.lib;dwmapi.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dwmapi.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
@@ -73,15 +72,17 @@
|
||||
<!-- Dependencies -->
|
||||
<ItemGroup>
|
||||
<!-- Manually include the .pri files from the app project as content files. -->
|
||||
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalAppLib\*.pri">
|
||||
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\*.pri">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</NativeReferenceFile>
|
||||
|
||||
<!-- Manually include the xbf files from the app project as content files -->
|
||||
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalAppLib\*.xbf">
|
||||
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\*.xbf">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</NativeReferenceFile>
|
||||
|
||||
<!--
|
||||
the packaging project wont recurse through our dependencies, you have to
|
||||
make sure that if you add a cppwinrt dependency to any of these projects,
|
||||
@@ -90,28 +91,10 @@
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
|
||||
<!-- Don't add a ProjectReference to TerminalApp here. If you do, the
|
||||
packaging project will find the TerminalApp.pri from both the TerminalAppLib
|
||||
and TerminalApp project, and we only want this lib project's pri file. We'll
|
||||
manually add a reference to the TerminalApp winmd and dll below, because we
|
||||
still need those. -->
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\TerminalApp.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\Microsoft.UI.Xaml.Markup\Microsoft.UI.Xaml.Markup.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<!-- A small helper for paths to the compiled cppwinrt projects -->
|
||||
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
|
||||
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Manually reference TerminalApp, since we can't use a ProjectReference. -->
|
||||
<Reference Include="TerminalApp">
|
||||
<HintPath>$(_BinRoot)\TerminalApp\TerminalApp.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
<ReferenceCopyLocalPaths Include="$(_BinRoot)\TerminalApp\TerminalApp.dll" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
This ItemGroup and the Globals PropertyGroup below it are required in order
|
||||
to enable F5 debugging for the unpackaged application
|
||||
@@ -127,20 +110,13 @@
|
||||
<!-- DON'T REDIRECT OUR OUTPUT -->
|
||||
<NoOutputRedirection>true</NoOutputRedirection>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.1.190405001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
|
||||
</Target>
|
||||
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="WindowsTerminal.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="AppHost.cpp" />
|
||||
<ClCompile Include="IslandWindow.cpp" />
|
||||
<ClCompile Include="NonClientIslandWindow.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="AppHost.h" />
|
||||
<ClInclude Include="BaseWindow.h" />
|
||||
<ClInclude Include="IslandWindow.h" />
|
||||
<ClInclude Include="NonClientIslandWindow.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="WindowsTerminal.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppHost.h"
|
||||
#include "..\..\types\Manager.h"
|
||||
#include "resource.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::UI;
|
||||
@@ -12,94 +10,8 @@ using namespace Windows::UI::Composition;
|
||||
using namespace Windows::UI::Xaml::Hosting;
|
||||
using namespace Windows::Foundation::Numerics;
|
||||
|
||||
// Routine Description:
|
||||
// - Retrieves the string resource from the current module with the given ID
|
||||
// from the resources files. See resource.h and the .rc definitions for valid IDs.
|
||||
// Arguments:
|
||||
// - id - Resource ID
|
||||
// Return Value:
|
||||
// - String resource retrieved from that ID.
|
||||
static std::wstring GetStringResource(const UINT id)
|
||||
{
|
||||
// Calling LoadStringW with a pointer-sized storage and no length will return a read-only pointer
|
||||
// directly to the resource data instead of copying it immediately into a buffer.
|
||||
LPWSTR readOnlyResource = nullptr;
|
||||
const auto length = LoadStringW(wil::GetModuleInstanceHandle(),
|
||||
id,
|
||||
reinterpret_cast<LPWSTR>(&readOnlyResource),
|
||||
0);
|
||||
|
||||
// However, the pointer and length given are NOT guaranteed to be zero-terminated
|
||||
// and most uses of this data will probably want a zero-terminated string.
|
||||
// So we're going to construct and return a std::wstring copy from the pointer/length
|
||||
// since those are certainly zero-terminated.
|
||||
return { readOnlyResource, gsl::narrow<size_t>(length) };
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Takes an image architecture and locates a string resource that maps to that architecture.
|
||||
// Arguments:
|
||||
// - imageArchitecture - An IMAGE_FILE_MACHINE architecture enum value
|
||||
// - See https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
|
||||
// Return Value:
|
||||
// - A string value representing the human-readable name of this architecture.
|
||||
static std::wstring ImageArchitectureToString(USHORT imageArchitecture)
|
||||
{
|
||||
// clang-format off
|
||||
const auto id = imageArchitecture == IMAGE_FILE_MACHINE_I386 ? IDS_X86_ARCHITECTURE :
|
||||
imageArchitecture == IMAGE_FILE_MACHINE_AMD64 ? IDS_AMD64_ARCHITECTURE :
|
||||
imageArchitecture == IMAGE_FILE_MACHINE_ARM64 ? IDS_ARM64_ARCHITECTURE :
|
||||
imageArchitecture == IMAGE_FILE_MACHINE_ARM ? IDS_ARM_ARCHITECTURE :
|
||||
IDS_UNKNOWN_ARCHITECTURE;
|
||||
// clang-format on
|
||||
|
||||
return GetStringResource(id);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Blocks the user from launching the application with a message box dialog and early exit
|
||||
// if the process architecture doesn't match the system platform native architecture.
|
||||
// - This is because the conhost.exe must match the condrv.sys on the system and the PTY
|
||||
// infrastructure that powers everything won't work if we have a mismatch.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
static void EnsureNativeArchitecture()
|
||||
{
|
||||
USHORT processMachine{};
|
||||
USHORT nativeMachine{};
|
||||
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
|
||||
if (processMachine != IMAGE_FILE_MACHINE_UNKNOWN && processMachine != nativeMachine)
|
||||
{
|
||||
const auto formatPattern = GetStringResource(IDS_ERROR_ARCHITECTURE_FORMAT);
|
||||
|
||||
const auto nativeArchitecture = ImageArchitectureToString(nativeMachine);
|
||||
const auto processArchitecture = ImageArchitectureToString(processMachine);
|
||||
|
||||
const auto lengthRequired = _scwprintf(formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
|
||||
const auto bufferSize = lengthRequired + 1;
|
||||
|
||||
std::wstring buffer;
|
||||
buffer.resize(bufferSize);
|
||||
|
||||
swprintf_s(buffer.data(), buffer.size(), formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
|
||||
|
||||
MessageBoxW(nullptr,
|
||||
buffer.data(),
|
||||
GetStringResource(IDS_ERROR_DIALOG_TITLE).data(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
{
|
||||
// Block the user from starting if they launched the incorrect architecture version of the project.
|
||||
// This should only be applicable to developer versions. The package installation process
|
||||
// should choose and install the correct one from the bundle.
|
||||
EnsureNativeArchitecture();
|
||||
|
||||
// Make sure to call this so we get WM_POINTER messages.
|
||||
EnableMouseInPointer(true);
|
||||
|
||||
@@ -108,16 +20,6 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
// provides an implementation of Windows.UI.Xaml.Application.
|
||||
AppHost host;
|
||||
|
||||
// Create a manager object for IPC.
|
||||
Manager manager;
|
||||
|
||||
// Create and register on connection callbacks from the manager into the application host.
|
||||
std::function<void(HANDLE)> onHandleConnection = std::bind(&AppHost::IncomingConnectionByHandle, &host, std::placeholders::_1);
|
||||
std::function<void(std::wstring_view, std::wstring_view)> onLaunchConnection = std::bind(&AppHost::IncomingConnectionByLaunch, &host, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Manager::s_RegisterOnConnection(onHandleConnection);
|
||||
Manager::s_RegisterOnConnection(onLaunchConnection);
|
||||
|
||||
// !!! LOAD BEARING !!!
|
||||
// This is _magic_. Do the initial loading of our settings *BEFORE* we
|
||||
// initialize our COM apartment type. This is because the Windows.Storage
|
||||
@@ -132,6 +34,9 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
// This works because Kenny Kerr said it would, and he wrote cpp/winrt, so he knows.
|
||||
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||
|
||||
// Initialize the Xaml Hosting Manager
|
||||
auto manager = Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
|
||||
|
||||
// Initialize the xaml content. This must be called AFTER the
|
||||
// WindowsXamlManager is initalized.
|
||||
host.Initialize();
|
||||
@@ -143,8 +48,5 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
|
||||
manager.NotifyExit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
|
||||
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.VCRTForwarders.140" version="1.0.0-rc" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190521.3" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.1.190405001-prerelease" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
|
||||
</packages>
|
||||
|
||||
@@ -48,6 +48,3 @@ Abstract:
|
||||
// * Media for ScaleTransform
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.ui.xaml.media.h>
|
||||
|
||||
#include <wil/resource.h>
|
||||
#include <wil/win32_helpers.h>
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by WindowsTerminal.rc
|
||||
//
|
||||
#define IDI_APPICON 101
|
||||
#define IDS_ERROR_DIALOG_TITLE 105
|
||||
#define IDS_ERROR_ARCHITECTURE_FORMAT 110
|
||||
#define IDS_X86_ARCHITECTURE 111
|
||||
#define IDS_AMD64_ARCHITECTURE 112
|
||||
#define IDS_ARM64_ARCHITECTURE 113
|
||||
#define IDS_ARM_ARCHITECTURE 114
|
||||
#define IDS_UNKNOWN_ARCHITECTURE 115
|
||||
// Used by Cascadia.EXE.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define IDI_APPICON 101
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "../TerminalApp/ColorScheme.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace TerminalApp;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
namespace TerminalAppUnitTests
|
||||
{
|
||||
class JsonTests
|
||||
{
|
||||
BEGIN_TEST_CLASS(JsonTests)
|
||||
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
|
||||
END_TEST_CLASS()
|
||||
|
||||
TEST_METHOD(ParseInvalidJson);
|
||||
TEST_METHOD(ParseSimpleColorScheme);
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
reader = std::unique_ptr<Json::CharReader>(Json::CharReaderBuilder::CharReaderBuilder().newCharReader());
|
||||
return true;
|
||||
}
|
||||
|
||||
Json::Value VerifyParseSucceeded(std::string content);
|
||||
void VerifyParseFailed(std::string content);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Json::CharReader> reader;
|
||||
};
|
||||
|
||||
Json::Value JsonTests::VerifyParseSucceeded(std::string content)
|
||||
{
|
||||
Json::Value root;
|
||||
std::string errs;
|
||||
const bool parseResult = reader->parse(content.c_str(), content.c_str() + content.size(), &root, &errs);
|
||||
VERIFY_IS_TRUE(parseResult, winrt::to_hstring(errs).c_str());
|
||||
return root;
|
||||
}
|
||||
void JsonTests::VerifyParseFailed(std::string content)
|
||||
{
|
||||
Json::Value root;
|
||||
std::string errs;
|
||||
const bool parseResult = reader->parse(content.c_str(), content.c_str() + content.size(), &root, &errs);
|
||||
VERIFY_IS_FALSE(parseResult);
|
||||
}
|
||||
|
||||
void JsonTests::ParseInvalidJson()
|
||||
{
|
||||
const std::string badJson{ "{ foo : bar : baz }" };
|
||||
VerifyParseFailed(badJson);
|
||||
}
|
||||
|
||||
void JsonTests::ParseSimpleColorScheme()
|
||||
{
|
||||
const std::string campbellScheme{ "{"
|
||||
"\"background\" : \"#0C0C0C\","
|
||||
"\"black\" : \"#0C0C0C\","
|
||||
"\"blue\" : \"#0037DA\","
|
||||
"\"brightBlack\" : \"#767676\","
|
||||
"\"brightBlue\" : \"#3B78FF\","
|
||||
"\"brightCyan\" : \"#61D6D6\","
|
||||
"\"brightGreen\" : \"#16C60C\","
|
||||
"\"brightPurple\" : \"#B4009E\","
|
||||
"\"brightRed\" : \"#E74856\","
|
||||
"\"brightWhite\" : \"#F2F2F2\","
|
||||
"\"brightYellow\" : \"#F9F1A5\","
|
||||
"\"cyan\" : \"#3A96DD\","
|
||||
"\"foreground\" : \"#F2F2F2\","
|
||||
"\"green\" : \"#13A10E\","
|
||||
"\"name\" : \"Campbell\","
|
||||
"\"purple\" : \"#881798\","
|
||||
"\"red\" : \"#C50F1F\","
|
||||
"\"white\" : \"#CCCCCC\","
|
||||
"\"yellow\" : \"#C19C00\""
|
||||
"}" };
|
||||
|
||||
const auto schemeObject = VerifyParseSucceeded(campbellScheme);
|
||||
auto scheme = ColorScheme::FromJson(schemeObject);
|
||||
VERIFY_ARE_EQUAL(L"Campbell", scheme.GetName());
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0xf2, 0xf2, 0xf2), scheme.GetForeground());
|
||||
VERIFY_ARE_EQUAL(ARGB(0, 0x0c, 0x0c, 0x0c), scheme.GetBackground());
|
||||
|
||||
std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable;
|
||||
auto campbellSpan = gsl::span<COLORREF>(&expectedCampbellTable[0], gsl::narrow<ptrdiff_t>(COLOR_TABLE_SIZE));
|
||||
Utils::InitializeCampbellColorTable(campbellSpan);
|
||||
|
||||
for (size_t i = 0; i < expectedCampbellTable.size(); i++)
|
||||
{
|
||||
const auto& expected = expectedCampbellTable.at(i);
|
||||
const auto& actual = scheme.GetTable().at(i);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "../TerminalApp/ColorScheme.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace TerminalApp;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
namespace TerminalAppUnitTests
|
||||
{
|
||||
// Unfortunately, these tests _WILL NOT_ work in our CI, until we have a lab
|
||||
// machine available that can run Windows version 18362. Until then, these
|
||||
// tests will be commented out. GH#1012 should move our CI to that version.
|
||||
// When that happens, these tests can be re-added.
|
||||
|
||||
// class SettingsTests
|
||||
// {
|
||||
// // Use a custom manifest to ensure that we can activate winrt types from
|
||||
// // our test. This property will tell taef to manually use this as the
|
||||
// // sxs manifest during this test class. It includes all the cppwinrt
|
||||
// // types we've defined, so if your test is crashing for an unknown
|
||||
// // reason, make sure it's included in that file.
|
||||
// // If you want to do anything XAML-y, you'll need to run yor test in a
|
||||
// // packaged context. See TabTests.cpp for more details on that.
|
||||
// BEGIN_TEST_CLASS(SettingsTests)
|
||||
// TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
|
||||
// END_TEST_CLASS()
|
||||
|
||||
// TEST_METHOD(TryCreateWinRTType);
|
||||
// };
|
||||
|
||||
// void SettingsTests::TryCreateWinRTType()
|
||||
// {
|
||||
// winrt::Microsoft::Terminal::Settings::TerminalSettings settings{};
|
||||
// VERIFY_IS_NOT_NULL(settings);
|
||||
// auto oldFontSize = settings.FontSize();
|
||||
// settings.FontSize(oldFontSize + 5);
|
||||
// auto newFontSize = settings.FontSize();
|
||||
// VERIFY_ARE_NOT_EQUAL(oldFontSize, newFontSize);
|
||||
// }
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user