Compare commits

...

15 commits

Author SHA1 Message Date
Mike Griese 01d5434afa This did not work either
I tried just making a dll for JUST the card extension interface, that the TerminalApp could reference and so would the cardextension.exe. That would get rid of the need for MUX? Right?

  This runs into all sorts of weird mdmerge errors that I don't recall how I fixed so FUCK IT I'm abandonning this project
2021-10-14 11:50:59 -05:00
Mike Griese e3b99b3ebf fuck you PRI175: 0x80073b0f - Processing Resources failed with error: Duplicate Entry
Seriously, this was going so fricken swimmingly and then this fricken error makes it totally impossible to build the package, that's garbage.

  Can't even build the CardExtensionPackage either, so obv I messed something simple up.
2021-10-14 11:26:56 -05:00
Mike Griese 2ec70cadd5 dead code cleanup 2021-10-14 06:23:17 -05:00
Mike Griese 1755a09ccf whoop whoop, the content thing worked 2021-10-14 06:19:19 -05:00
Mike Griese ff7c5d32af start moving code into PaneContent classes 2021-10-13 20:27:38 -05:00
Mike Griese e3cbc24ae7 minor cleanup 2021-10-13 14:23:13 -05:00
Mike Griese 03caae7104 This actually keeps the card alive long enough to be useful 2021-10-13 12:47:38 -05:00
Mike Griese e38b38ab8f It's unclear why the actions don't seem to work 2021-10-13 11:52:30 -05:00
Mike Griese 9ec377f724 Get an adaptivecard rendering in the Terminal
I needed a FWElement, because a grid is not a Control, and a AC is a FWElement too.
2021-10-13 10:07:58 -05:00
Mike Griese bbcc3e724f You need to use a Control, not a UserControl. A TextBox is not a subclass of UserControl 2021-10-13 08:27:41 -05:00
Mike Griese da44263cf3 Wire up the hacktion for testing purposes 2021-10-13 08:12:16 -05:00
Mike Griese 1b736f4663 fix the build 2021-10-07 12:36:53 -05:00
Mike Griese c7cb3ce862 More things we might need for Non-Terminal content, #997 2021-10-07 11:59:28 -05:00
Mike Griese b4fd3f3638 These are things I might need for #997 2021-10-07 11:58:27 -05:00
Mike Griese 0acb4d93bf Allow a Pane to host a UserControl instead of a TermControl 2021-10-07 11:57:11 -05:00
69 changed files with 2589 additions and 235 deletions

View file

@ -5,6 +5,7 @@
<!-- Dependencies that we can turn on to force override for testing purposes before uploading. -->
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/ms/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
<add key="NugetDefault" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />

View file

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29001.49
# Visual Studio Version 17
VisualStudioVersion = 17.0.31717.71
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Terminal", "Terminal", "{59840756-302F-44DF-AA47-441A9D673202}"
EndProject
@ -400,6 +400,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsTerminal.UIA.Tests",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-ms-win-core-synch-l1-2-0", "src\api-ms-win-core-synch-l1-2-0\api-ms-win-core-synch-l1-2-0.vcxproj", "{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CardExtension", "src\cascadia\CardExtension\CardExtension.vcxproj", "{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {27B5AAEB-A548-44CF-9777-F8BAA32AF7AE}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
EndProjectSection
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CardExtensionPackage", "src\cascadia\CardExtensionPackage\CardExtensionPackage.wapproj", "{4F79071E-22BA-4310-9C08-68A1D31C64D5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ICardExtension", "src\cascadia\ICardExtension\ICardExtension.vcxproj", "{2418E803-264A-479C-BFDC-915182BCBF12}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
@ -3339,6 +3353,158 @@ Global
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x64.Build.0 = Release|x64
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.ActiveCfg = Release|Win32
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|Any CPU.ActiveCfg = Debug|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|DotNet_x64Test.ActiveCfg = Debug|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|DotNet_x86Test.ActiveCfg = Debug|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|ARM.ActiveCfg = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|Any CPU.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|ARM.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}.Release|x86.Build.0 = Release|Win32
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|Any CPU.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|Any CPU.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|Any CPU.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM64.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM64.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|ARM64.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x64Test.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x64Test.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x64Test.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x86Test.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x86Test.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|DotNet_x86Test.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x64.ActiveCfg = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x64.Build.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x64.Deploy.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x86.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x86.Build.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.AuditMode|x86.Deploy.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|Any CPU.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|ARM.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|ARM64.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|ARM64.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|ARM64.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|DotNet_x64Test.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|DotNet_x86Test.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x64.ActiveCfg = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x64.Build.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x64.Deploy.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x86.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x86.Build.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Debug|x86.Deploy.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|Any CPU.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|Any CPU.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|Any CPU.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM64.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x64Test.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x64Test.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x64Test.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x86Test.ActiveCfg = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x86Test.Build.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|DotNet_x86Test.Deploy.0 = Debug|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x64.ActiveCfg = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x64.Build.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x64.Deploy.0 = Debug|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x86.ActiveCfg = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x86.Build.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Fuzzing|x86.Deploy.0 = Debug|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|Any CPU.ActiveCfg = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|ARM.ActiveCfg = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|ARM64.ActiveCfg = Release|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|ARM64.Build.0 = Release|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|ARM64.Deploy.0 = Release|ARM64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|DotNet_x64Test.ActiveCfg = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|DotNet_x86Test.ActiveCfg = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x64.ActiveCfg = Release|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x64.Build.0 = Release|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x64.Deploy.0 = Release|x64
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x86.ActiveCfg = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x86.Build.0 = Release|x86
{4F79071E-22BA-4310-9C08-68A1D31C64D5}.Release|x86.Deploy.0 = Release|x86
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|Any CPU.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|Any CPU.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|ARM.ActiveCfg = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|ARM.Build.0 = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|ARM64.ActiveCfg = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|ARM64.Build.0 = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|DotNet_x64Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|DotNet_x64Test.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|DotNet_x86Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|DotNet_x86Test.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|x64.ActiveCfg = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|x64.Build.0 = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|x86.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.AuditMode|x86.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|Any CPU.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|ARM.ActiveCfg = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|ARM.Build.0 = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|ARM64.ActiveCfg = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|ARM64.Build.0 = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|x64.ActiveCfg = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|x64.Build.0 = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|x86.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Debug|x86.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|Any CPU.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|ARM.ActiveCfg = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|ARM.Build.0 = Debug|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|ARM64.Build.0 = Debug|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|DotNet_x64Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|DotNet_x64Test.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|DotNet_x86Test.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|DotNet_x86Test.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|x64.ActiveCfg = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|x64.Build.0 = Debug|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|x86.ActiveCfg = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Fuzzing|x86.Build.0 = Debug|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|Any CPU.ActiveCfg = Release|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|ARM.ActiveCfg = Release|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|ARM.Build.0 = Release|ARM
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|ARM64.ActiveCfg = Release|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|ARM64.Build.0 = Release|ARM64
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|x64.ActiveCfg = Release|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|x64.Build.0 = Release|x64
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|x86.ActiveCfg = Release|Win32
{2418E803-264A-479C-BFDC-915182BCBF12}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3438,6 +3604,9 @@ Global
{C323DAEE-B307-4C7B-ACE5-7293CBEFCB5B} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{F19DACD5-0C6E-40DC-B6E4-767A3200542C} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B} = {2D17E75D-2DDC-42C4-AD70-704D95A937AE}
{4F79071E-22BA-4310-9C08-68A1D31C64D5} = {2D17E75D-2DDC-42C4-AD70-704D95A937AE}
{2418E803-264A-479C-BFDC-915182BCBF12} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View file

@ -0,0 +1,27 @@
<?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 -->
<!-- See https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/xaml-islands -->
<!-- "maxversiontested" is CASE SENSITIVE. Do not change this.-->
<!-- DO NOT ADVANCE PAST 18362. The OS has a bug where it won't recognize 19041 as bigger. -->
<!-- This will cause unpackaged activation failures in XAML Islands. -->
<!-- (We use unpackaged activation in test scenarios.) See GH#10265. -->
<maxversiontested Id="10.0.18362.0"/>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>

View file

@ -0,0 +1,91 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
#if defined(WT_BRANDING_RELEASE)
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"
IDI_APPICON_HC_BLACK ICON "..\\..\\..\\res\\terminal\\images\\terminal_contrast-black.ico"
IDI_APPICON_HC_WHITE ICON "..\\..\\..\\res\\terminal\\images\\terminal_contrast-white.ico"
#elif defined(WT_BRANDING_PREVIEW)
IDI_APPICON ICON "..\\..\\..\\res\\terminal\\images-Pre\\terminal.ico"
IDI_APPICON_HC_BLACK ICON "..\\..\\..\\res\\terminal\\images-Pre\\terminal_contrast-black.ico"
IDI_APPICON_HC_WHITE ICON "..\\..\\..\\res\\terminal\\images-Pre\\terminal_contrast-white.ico"
#else
IDI_APPICON ICON "..\\..\\..\\res\\terminal\\images-Dev\\terminal.ico"
IDI_APPICON_HC_BLACK ICON "..\\..\\..\\res\\terminal\\images-Dev\\terminal_contrast-black.ico"
IDI_APPICON_HC_WHITE ICON "..\\..\\..\\res\\terminal\\images-Dev\\terminal_contrast-white.ico"
#endif
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<PropertyGroup Label="Globals">
<ProjectGuid>{CA5CAD1A-1234-4A9D-5678-857A9D17CB1B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CardExtension</RootNamespace>
<ProjectName>CardExtension</ProjectName>
<TargetName>CardExtension</TargetName>
<ConfigurationType>Application</ConfigurationType>
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
<ApplicationType>Windows Store</ApplicationType>
<WindowsStoreApp>true</WindowsStoreApp>
<WindowsAppContainer>false</WindowsAppContainer>
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
<PgoTarget>true</PgoTarget>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<ItemDefinitionGroup>
<ClCompile>
<SDLCheck>true</SDLCheck>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>gdi32.lib;dwmapi.lib;Shcore.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<GenerateManifest>true</GenerateManifest>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<!-- Source Files -->
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="main.cpp" />
<ClCompile Include="ContentProcessMain.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CardExtension.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="CardExtension.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<!-- Even though we do have proper recursive dependencies, we want to keep some of these here
so that the AppX Manifest contains their activatable classes. -->
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj" /> -->
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" /> -->
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" /> -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\ICardExtension\ICardExtension.vcxproj" />
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\dll\TerminalApp.vcxproj" /> -->
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\Remoting\dll\Microsoft.Terminal.Remoting.vcxproj" /> -->
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
<!-- <ProjectReference Include="$(OpenConsoleDir)src\cascadia\WinRTUtils\WinRTUtils.vcxproj">
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference> -->
</ItemGroup>
<!-- Manually add a reference to Core here. We need this so MDMERGE will know
where the Core types are defined. However, we need to do it exactly like this,
because the Core project is a lib not a dll, so it can't be ProjectReference'd
like everything else. It does get built into TerminalControl.dll, so we don't
need to worry about that. -->
<!-- <ItemGroup>
<Reference Include="Microsoft.Terminal.Core">
<HintPath>$(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>true</Private>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
</Reference>
</ItemGroup> -->
<!--
This ItemGroup and the Globals PropertyGroup below it are required in order
to enable F5 debugging for the unpackaged application
-->
<ItemGroup>
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_general.xml" />
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_local_windows.xml" />
</ItemGroup>
<PropertyGroup Label="Globals">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<!-- <Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.6.2-prerelease.210818003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.6.2-prerelease.210818003\build\native\Microsoft.UI.Xaml.targets')" /> -->
<!-- <Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" /> -->
<!-- <Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.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.6.2-prerelease.210818003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.6.2-prerelease.210818003\build\native\Microsoft.UI.Xaml.targets'))" /> -->
<!-- <Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" /> -->
<!-- <Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" /> -->
<!-- <Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets'))" /> -->
<!-- <Error Condition="!Exists('..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets'))" /> -->
</Target>
<!-- <Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" /> -->
<!-- <Import Project="..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets" Condition="Exists('..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets')" /> -->
</Project>

View file

@ -0,0 +1,219 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "resource.h"
#include "../types/inc/User32Utils.hpp"
#include <WilErrorReporting.h>
using namespace winrt;
winrt::hstring semiAdvancedCard{
LR"({
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Publish Adaptive Card schema",
"weight": "bolder",
"size": "medium"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg",
"size": "small",
"style": "person"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Matt Hidinger",
"weight": "bolder",
"wrap": true
},
{
"type": "TextBlock",
"spacing": "none",
"text": "Created {{DATE(2017-02-14T06:08:39Z, SHORT)}}",
"isSubtle": true,
"wrap": true
}
]
}
]
},
{
"type": "TextBlock",
"text": "Now that we have defined the main rules and features of the format, we need to produce a schema and publish it to GitHub. The schema will be the starting point of our reference documentation.",
"wrap": true
},
{
"type": "Input.Text",
"id": "comment",
"isMultiline": true,
"placeholder": "Enter your comment"
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "OK"
},
{
"type": "Action.OpenUrl",
"title": "View",
"url": "https://adaptivecards.io"
},
{
"type": "Action.OpenUrl",
"title": "Hey look I came from an extension",
"url": "https://adaptivecards.io"
}
]
})"
};
namespace winrt::CardExtension::implementation
{
class MyCard : public winrt::implements<MyCard, winrt::TerminalApp::ICardExtension>
{
public:
winrt::hstring GetJson()
{
return semiAdvancedCard;
}
};
}
// We keep a weak ref to our ContentProcess singleton here.
// Why?
//
// We need to always return the _same_ ContentProcess when someone comes to
// instantiate this class. So we want to track the single instance we make. We
// also want to track when the last outstanding reference to this object is
// removed. If we're keeping a strong ref, then the ref count will always be > 1
winrt::weak_ref<winrt::TerminalApp::ICardExtension> g_weak{ nullptr };
wil::unique_event g_canExitThread;
struct ExtensionFactory : implements<ExtensionFactory, IClassFactory>
{
ExtensionFactory(winrt::guid g) :
_guid{ g } {};
HRESULT __stdcall CreateInstance(IUnknown* outer, GUID const& iid, void** result) noexcept final
{
*result = nullptr;
if (outer)
{
return CLASS_E_NOAGGREGATION;
}
if (!g_weak)
{
// Instantiate the ContentProcess here
auto strong{ winrt::make<winrt::CardExtension::implementation::MyCard>() };
// Now, create a weak ref to that ContentProcess object.
winrt::weak_ref<winrt::TerminalApp::ICardExtension> weak{ strong };
// Stash away that weak ref for future callers.
g_weak = weak;
return strong.as(iid, result);
}
else
{
auto strong = g_weak.get();
// !! LOAD BEARING !! If you set this event in the _first_ branch
// here, when we first create the object, then there will be _no_
// referernces to the ContentProcess object for a small slice. We'll
// stash the ContentProcess in the weak_ptr, and return it, and at
// that moment, there will be 0 outstanding references, it'll dtor,
// and we'll ExitProcess.
//
// Instead, set the event here, once there's already a reference
// outside of just the weak one we keep. Experimentation showed this
// waw always hit when creating the ContentProcess at least once.
g_canExitThread.SetEvent();
return strong.as(iid, result);
}
}
HRESULT __stdcall LockServer(BOOL) noexcept final
{
return S_OK;
}
private:
winrt::guid _guid;
};
//winrt::guid GUID(const winrt::hstring& s)
//{
// struct __declspec(uuid(s))
// {
// } foo;
// __uuidof(decltype(foo));
//}
//
//#define GUID(guid, name) \
// struct __declspec(uuid(guid)) \
// { \
// } foo; \
// __uuidof(decltype(foo));
struct __declspec(uuid("76b3f18c-89ed-4a29-98ac-2096395e7c32")) hack
{
};
static void doContentProcessThing(const HANDLE& eventHandle)
{
// 76b3f18c-89ed-4a29-98ac-2096395e7c32
winrt::guid extensionGuid{ __uuidof(hack) };
// winrt::guid test{ GUID("76b3f18c-89ed-4a29-98ac-2096395e7c32") };
// !! LOAD BEARING !! - important to be a MTA for these COM calls.
winrt::init_apartment();
DWORD registrationHostClass{};
check_hresult(CoRegisterClassObject(extensionGuid,
make<ExtensionFactory>(extensionGuid).get(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&registrationHostClass));
// Signal the event handle that was passed to us that we're now set up and
// ready to go.
SetEvent(eventHandle);
CloseHandle(eventHandle);
}
void TryRunAsContentProcess()
{
HANDLE eventHandle{ INVALID_HANDLE_VALUE };
g_canExitThread = wil::unique_event{ CreateEvent(nullptr, true, false, nullptr /*L"ContentProcessReady"*/) };
doContentProcessThing(eventHandle);
WaitForSingleObject(g_canExitThread.get(), INFINITE);
// This is the conhost thing - if we ExitThread the main thread, the
// other threads can keep running till one calls ExitProcess.
ExitThread(0);
}

View file

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "resource.h"
#include "../types/inc/User32Utils.hpp"
#include <WilErrorReporting.h>
// !! BODGY !!
// Manually use the resources from TerminalApp as our resources.
// The WindowsTerminal project doesn't actually build a Resources.resw file, but
// we still need to be able to localize strings for the tray icon menu. Anything
// you want localized for WindowsTerminal.exe should be stuck in
// ...\TerminalApp\Resources\en-US\Resources.resw
// #include <LibraryResources.h>
// UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources");
void TryRunAsContentProcess();
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
// If we _are_ a content process, then this function will call ExitThread(),
// after spawning some COM threads to deal with inbound COM requests to the
// ContentProcess object.
TryRunAsContentProcess();
// If we weren't a content process, then we'll just move on, and do the
// normal WindowsTerminal thing.
return 0;
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.6.2-prerelease.210818003" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.3.210521003" targetFramework="native" />
</packages>

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"

View file

@ -0,0 +1,90 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- pch.h
Abstract:
- Contains external headers to include in the precompile phase of console build process.
- Avoid including internal project headers. Instead include them only in the classes that need them (helps with test project building).
--*/
#pragma once
// Ignore checked iterators warning from VC compiler.
#define _SCL_SECURE_NO_WARNINGS
// Block minwindef.h min/max macros to prevent <algorithm> conflict
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#define NOMCX
#define NOHELP
#define NOCOMM
#include <unknwn.h>
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#include <windows.h>
#include <UIAutomation.h>
#include <cstdlib>
#include <cstring>
#include <shellscalingapi.h>
#include <windowsx.h>
#include <ShObjIdl.h>
// Manually include til after we include Windows.Foundation to give it winrt superpowers
#define BLOCK_TIL
#include "../inc/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 <wil/cppwinrt.h>
// Needed just for XamlIslands to work at all:
#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>
// Additional headers for various xaml features. We need:
// * Core so we can resume_foreground with CoreDispatcher
// * Controls for grid
// * Media for ScaleTransform
// * ApplicationModel for finding the path to wt.exe
// * Primitives for Popup (used by GetOpenPopupsForXamlRoot)
#include <winrt/Windows.UI.Core.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.ApplicationModel.h>
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
#include <winrt/TerminalApp.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
// #include <winrt/Microsoft.Terminal.Remoting.h>
#include <winrt/Microsoft.Terminal.Control.h>
#include <wil/resource.h>
#include <wil/win32_helpers.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DECLARE_PROVIDER(g_hWindowsTerminalProvider);
#include <telemetry/ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
// For commandline argument processing
#include <shellapi.h>
#include <processenv.h>
#include <WinUser.h>
#include "til.h"

View file

@ -0,0 +1,18 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by CardExtension.rc
//
#define IDI_APPICON 201
#define IDI_APPICON_HC_BLACK 202
#define IDI_APPICON_HC_WHITE 203
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -0,0 +1,138 @@
<?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="Configuration">
<!--
These two properties are very important!
Without them, msbuild will stomp MinVersion and MaxVersionTested in the
Package.appxmanifest and replace them with whatever our values for
TargetPlatformMinVersion and TargetPlatformVersion are.
-->
<AppxOSMinVersionReplaceManifestVersion>false</AppxOSMinVersionReplaceManifestVersion>
<AppxOSMaxVersionTestedReplaceManifestVersion>false</AppxOSMaxVersionTestedReplaceManifestVersion>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{4F79071E-22BA-4310-9C08-68A1D31C64D5}</ProjectGuid>
<EntryPointProjectUniqueName>..\CardExtension\CardExtension.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">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<!-- Resources -->
<!-- This resw only defines things that are used in this package's AppxManifest,
so it's not in the common resource items. -->
<PRIResource Include="Resources\en-US\Resources.resw" />
<PRIResource Include="Resources\Resources.resw" />
<OCResourceDirectory Include="Resources" />
</ItemGroup>
<!-- This is picked up by CascadiaResources.build.items. -->
<PropertyGroup Condition="'$(WindowsTerminalBranding)'==''">
<WindowsTerminalAssetSuffix>-Dev</WindowsTerminalAssetSuffix>
</PropertyGroup>
<PropertyGroup Condition="'$(WindowsTerminalBranding)'=='Preview'">
<WindowsTerminalAssetSuffix>-Pre</WindowsTerminalAssetSuffix>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\CascadiaResources.build.items" />
<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />
<ItemGroup>
<ProjectReference Include="..\CardExtension\CardExtension.vcxproj" />
</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)">
<!-- Blank the SourceProject here to vend all files into the root of the package. -->
<SourceProject>
</SourceProject>
<!-- Replace the filename for wt/wtd.exe with the one the manifest wants. -->
<TargetPath Condition="'%(Filename)' == 'wt' and '%(Extension)' == '.exe'">$(OCExecutionAliasName).exe</TargetPath>
</_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>
<!-- Only for MSBuild versions < 16.3.0 -->
<_GenerateProjectPriFileDependsOn Condition="$(MSBuildVersion) &lt; '16.3.0'">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>
<!-- VS 16.3.0 added a rule to the WAP packaging project that removes all non-WAP payload, which we were relying on to
roll up our subproject resources. We have to suppress that rule but keep part of its logic, because that rule is
where the AppxPackagePayload items are created. -->
<PropertyGroup>
<WapProjBeforeGenerateAppxManifestDependsOn>
$([MSBuild]::Unescape('$(WapProjBeforeGenerateAppxManifestDependsOn.Replace('_RemoveAllNonWapUWPItems', '_OpenConsoleRemoveAllNonWapUWPItems'))'))
</WapProjBeforeGenerateAppxManifestDependsOn>
</PropertyGroup>
<Target Name="_OpenConsoleRemoveAllNonWapUWPItems">
<ItemGroup>
<AppxPackagePayload Include="@(WapProjPackageFile)" />
<AppxUploadPackagePayload Include="@(UploadWapProjPackageFile)" />
<!-- 16.3.0 - remove non-resources.pri PRI files since we just forced them back in. -->
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
<AppxUploadPackagePayload Remove="@(AppxUploadPackagePayload)" Condition="'%(Extension)' == '.pri' and '%(Filename)' != 'resources'" />
</ItemGroup>
</Target>
<!-- **BEGIN VC LIBS HACK** -->
<!--
For our release builds, we're just going to integrate the UWPDesktop CRT into our package and delete the package dependencies.
It's very difficult for users who do not have access to the store to get our dependency packages, and we want to be robust
and deployable everywhere. Since these libraries can be redistributed, it's easiest if we simply redistribute them.
See also the "VC LIBS HACK" section in WindowsTerminal.vcxproj.
-->
<!-- This target removes the FrameworkSdkReferences from before the AppX package targets manifest generation happens.
This is part of the generic machinery that applies to every AppX. -->
<Target Name="_OpenConsoleStripAllDependenciesFromPackageFirstManifest" BeforeTargets="_GenerateCurrentProjectAppxManifest">
<ItemGroup Condition="'$(WindowsTerminalOfficialBuild)'=='true'">
<FrameworkSdkReference Remove="@(FrameworkSdkReference)" />
</ItemGroup>
</Target>
<!-- This target removes the FrameworkSdkPackages from before the *desktop bridge* manifest generation happens. -->
<Target Name="_OpenConsoleStripAllDependenciesFromPackageSecondManifest" BeforeTargets="_GenerateDesktopBridgeAppxManifest" DependsOnTargets="_ResolveVCLibDependencies">
<ItemGroup Condition="'$(WindowsTerminalOfficialBuild)'=='true'">
<FrameworkSdkPackage Remove="@(FrameworkSdkPackage)" />
</ItemGroup>
</Target>
<!-- **END VC LIBS HACK** -->
<!-- This is required to get the package dependency in the AppXManifest. -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\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.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View file

@ -0,0 +1,16 @@
<html>
<head><title>Placeholder 3rd-party Notices</title></head>
<body>
<h1>Windows Terminal (Dev)</h1>
<p>
This is a development build of Windows Terminal. The third-party notices
for this project can be found on
<a href="https://github.com/microsoft/terminal/blob/main/NOTICE.md">the
project's GitHub page</a>.
</p>
<p>
During a branded release build, this file is replaced with the content of
<code>NOTICES.md</code> from the root of the repository.
</p>
</body>
</html>

View file

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
xmlns:uap7="http://schemas.microsoft.com/appx/manifest/uap/windows10/7"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap uap3">
<Identity
Name="Microsoft.CardExtensionPackage"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="1.0.0.0" />
<Properties>
<DisplayName>Card Extension Package</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="ms-resource:AppName"
Description="ms-resource:AppDescription"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile
Wide310x150Logo="Images\Wide310x150Logo.png"
Square71x71Logo="Images\SmallTile.png"
Square310x310Logo="Images\LargeTile.png"
ShortName="ms-resource:AppShortName">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
<uap:ShowOn Tile="square310x310Logo"/>
</uap:ShowNameOnTiles>
</uap:DefaultTile>
</uap:VisualElements>
<Extensions>
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.terminal.cards"
Id="TestCard"
DisplayName="Test Card Extension"
Description="test test test"
PublicFolder="Public">
<uap3:Properties>
<Clsid>{76b3f18c-89ed-4a29-98ac-2096395e7c32}</Clsid>
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer DisplayName="CardExtension" Executable="CardExtension.exe">
<com:Class Id="76b3f18c-89ed-4a29-98ac-2096395e7c32"/>
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

View file

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppName" xml:space="preserve">
<value>Windows Terminal</value>
</data>
<data name="AppNameDev" xml:space="preserve">
<value>Windows Terminal Dev</value>
</data>
<data name="AppNamePre" xml:space="preserve">
<value>Windows Terminal Preview</value>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal Dev</value>
</data>
<data name="AppShortNamePre" xml:space="preserve">
<value>Terminal Preview</value>
</data>
</root>

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>The New Windows Terminal</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Windows Terminal with a preview of upcoming features</value>
</data>
</root>

View file

@ -63,6 +63,7 @@
<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />
<ItemGroup>
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
<ProjectReference Include="..\CardExtension\CardExtension.vcxproj" />
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
<ProjectReference Include="..\..\host\proxy\Host.Proxy.vcxproj" />
<ProjectReference Include="..\TerminalAzBridge\TerminalAzBridge.vcxproj" />
@ -80,7 +81,8 @@
<SourceProject>
</SourceProject>
<!-- Replace the filename for wt/wtd.exe with the one the manifest wants. -->
<TargetPath Condition="'%(Filename)' == 'wt' and '%(Extension)' == '.exe'">$(OCExecutionAliasName).exe</TargetPath>
<TargetPath Condition="('%(Filename)' == 'wt' or '%(Filename)' == 'CardExtension') and '%(Extension)' == '.exe'">$(OCExecutionAliasName).exe</TargetPath>
<!-- <TargetPath Condition="'%(Filename)' == 'wt' and '%(Extension)' == '.exe'">$(OCExecutionAliasName).exe</TargetPath> -->
</_FilteredNonWapProjProjectOutput>
</ItemGroup>
</Target>

View file

@ -68,6 +68,11 @@
<uap3:Name>com.microsoft.windows.terminal.settings</uap3:Name>
</uap3:AppExtensionHost>
</uap3:Extension>
<uap3:Extension Category="windows.appExtensionHost">
<uap3:AppExtensionHost>
<uap3:Name>com.microsoft.windows.terminal.cards</uap3:Name>
</uap3:AppExtensionHost>
</uap3:Extension>
<uap5:Extension Category="windows.startupTask">
<uap5:StartupTask
TaskId="StartTerminalOnLoginTask"
@ -96,6 +101,17 @@
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
<!-- <uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.terminal.cards"
Id="TestCard"
DisplayName="Test Card Extension"
Description="test test test"
PublicFolder="Public">
<uap3:Properties>
<Clsid>{76b3f18c-89ed-4a29-98ac-2096395e7c32}</Clsid>
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension> -->
<com:Extension Category="windows.comInterface">
<com:ComInterface>
<com:ProxyStub Id="3171DE52-6EFA-4AEF-8A9F-D02BD67E7A4F" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
@ -111,6 +127,9 @@
<com:ExeServer DisplayName="WindowsTerminal" Executable="WindowsTerminal.exe">
<com:Class Id="E12CFF52-A866-4C77-9A90-F570A7AA2C6B"/>
</com:ExeServer>
<!-- <com:ExeServer DisplayName="CardExtension" Executable="CardExtension.exe">
<com:Class Id="76b3f18c-89ed-4a29-98ac-2096395e7c32"/>
</com:ExeServer> -->
<com:SurrogateServer DisplayName="WindowsTerminalShellExt">
<com:Class Id="9f156763-7844-4dc4-b2b1-901f640f5155" Path="WindowsTerminalShellExt.dll" ThreadingModel="STA"/>
</com:SurrogateServer>

View file

@ -0,0 +1,16 @@
#include "pch.h"
#include "Class.h"
#include "Class.g.cpp"
namespace winrt::Microsoft::CardExtension::implementation
{
int32_t Class::MyProperty()
{
throw hresult_not_implemented();
}
void Class::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "Class.g.h"
namespace winrt::Microsoft::CardExtension::implementation
{
struct Class : ClassT<Class>
{
Class() = default;
int32_t MyProperty();
void MyProperty(int32_t value);
};
}
namespace winrt::Microsoft::CardExtension::factory_implementation
{
struct Class : ClassT<Class, implementation::Class>
{
};
}

View file

@ -0,0 +1,9 @@
namespace Microsoft.CardExtension
{
[default_interface]
runtimeclass Class
{
Class();
Int32 MyProperty;
}
}

View file

@ -0,0 +1,3 @@
EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE

View file

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{2418e803-264a-479c-bfdc-915182bcbf12}</ProjectGuid>
<ProjectName>CardExtension</ProjectName>
<RootNamespace>Microsoft.CardExtension</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22000.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="PropertySheet.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level4</WarningLevel>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
<AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
<ModuleDefinitionFile>ICardExtension.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="Class.h">
<DependentUpon>Class.idl</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Class.cpp">
<DependentUpon>Class.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="..\TerminalApp\ICardExtension.idl" />
<Midl Include="Class.idl" />
</ItemGroup>
<ItemGroup>
<None Include="ICardExtension.def" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="PropertySheet.props" />
<Text Include="readme.txt">
<DeploymentContent>false</DeploymentContent>
</Text>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<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.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resources">
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="Class.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="Class.idl" />
<Midl Include="..\TerminalApp\ICardExtension.idl" />
</ItemGroup>
<ItemGroup>
<None Include="ICardExtension.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<!--
To customize common C++/WinRT project properties:
* right-click the project node
* expand the Common Properties item
* select the C++/WinRT property page
For more advanced scenarios, and complete documentation, please see:
https://github.com/Microsoft/cppwinrt/tree/master/nuget
-->
<PropertyGroup />
<ItemDefinitionGroup />
</Project>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.210806.1" targetFramework="native" />
</packages>

View file

@ -0,0 +1 @@
#include "pch.h"

View file

@ -0,0 +1,4 @@
#pragma once
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>

View file

@ -0,0 +1,23 @@
========================================================================
C++/WinRT ICardExtension Project Overview
========================================================================
This project demonstrates how to get started authoring Windows Runtime
classes directly with standard C++, using the C++/WinRT SDK component
to generate implementation headers from interface (IDL) files. The
generated Windows Runtime component binary and WinMD files should then
be bundled with the Universal Windows Platform (UWP) app consuming them.
Steps:
1. Create an interface (IDL) file to define your Windows Runtime class,
its default interface, and any other interfaces it implements.
2. Build the project once to generate module.g.cpp, module.h.cpp, and
implementation templates under the "Generated Files" folder, as
well as skeleton class definitions under "Generated Files\sources".
3. Use the skeleton class definitions for reference to implement your
Windows Runtime classes.
========================================================================
Learn more about C++/WinRT here:
http://aka.ms/cppwinrt/
========================================================================

View file

@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "AdaptiveCardContent.h"
#include "AdaptiveCardContent.g.cpp"
using namespace winrt::AdaptiveCards::Rendering::Uwp;
// using namespace winrt::AdaptiveCards::ObjectModel::Uwp;
namespace winrt::TerminalApp::implementation
{
AdaptiveCardContent::AdaptiveCardContent() {}
bool AdaptiveCardContent::InitFromString(const winrt::hstring& jsonString)
{
try
{
AdaptiveCardRenderer renderer{};
// TODO!: double check if this VVV throws or just logs
auto card{ winrt::AdaptiveCards::Rendering::Uwp::AdaptiveCard::FromJsonString(jsonString) };
if (!card.AdaptiveCard())
{
return false;
}
_renderedCard = renderer.RenderAdaptiveCard(card.AdaptiveCard());
_root = _renderedCard.FrameworkElement();
_renderedCard.Action([](const auto& /*s*/, const AdaptiveActionEventArgs& args) {
auto a = 0;
a++;
a;
if (const auto& openUrlAction{ args.Action().try_as<AdaptiveOpenUrlAction>() })
{
// await Launcher.LaunchUriAsync(openUrlAction.Url);
}
else if (const auto& showCardAction{ args.Action().try_as<AdaptiveShowCardAction>() })
{
// This is only fired if, in HostConfig, you set the ShowCard
// ActionMode to Popup. Otherwise, the renderer will
// automatically display the card inline without firing this
// event.
}
else if (const auto& submitAction{ args.Action().try_as<AdaptiveSubmitAction>() })
{
// Get the data and inputs
const auto data{ submitAction.DataJson().Stringify() };
const auto inputs{ args.Inputs().AsJson().Stringify() };
// Process them as desired
data;
inputs;
auto a = 0;
a++;
a;
}
});
return true;
}
CATCH_LOG();
return false;
}
winrt::Windows::UI::Xaml::FrameworkElement AdaptiveCardContent::GetRoot()
{
return _root;
}
winrt::Windows::Foundation::Size AdaptiveCardContent::MinSize()
{
return Windows::Foundation::Size{ 1, 1 };
}
void AdaptiveCardContent::Focus()
{
// TODO!?
// UIElement.GetChildrenInTabFocusOrder maybe?
}
void AdaptiveCardContent::Close()
{
}
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs AdaptiveCardContent::GetTerminalArgsForPane() const
{
return nullptr;
}
}

View file

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "AdaptiveCardContent.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
struct AdaptiveCardContent : AdaptiveCardContentT<AdaptiveCardContent>
{
AdaptiveCardContent();
bool InitFromString(const winrt::hstring& jsonString);
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
winrt::Windows::Foundation::Size MinSize();
void Focus();
void Close();
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane() const;
private:
winrt::Windows::UI::Xaml::FrameworkElement _root{ nullptr };
winrt::AdaptiveCards::Rendering::Uwp::RenderedAdaptiveCard _renderedCard{ nullptr };
};
}

View file

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "IPaneContent.idl";
namespace TerminalApp
{
[default_interface] runtimeclass AdaptiveCardContent : IPaneContent
{
// AdaptiveCardContent();
// InitFromString(String json);
}
}

View file

@ -5,6 +5,7 @@
#include "App.h"
#include "TerminalPage.h"
#include "AdaptiveCardContent.h"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "../../types/inc/utils.hpp"
#include "Utils.h"
@ -913,4 +914,285 @@ namespace winrt::TerminalApp::implementation
}
}
}
winrt::hstring simpleCard{
LR"({
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Here is a ninja cat"
},
{
"type": "Image",
"url": "http://adaptivecards.io/content/cats/1.png"
}
]
})"
};
winrt::hstring advancedCard{
LR"({
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Publish Adaptive Card schema",
"weight": "bolder",
"size": "medium"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg",
"size": "small",
"style": "person"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Matt Hidinger",
"weight": "bolder",
"wrap": true
},
{
"type": "TextBlock",
"spacing": "none",
"text": "Created {{DATE(2017-02-14T06:08:39Z, SHORT)}}",
"isSubtle": true,
"wrap": true
}
]
}
]
}
]
},
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Now that we have defined the main rules and features of the format, we need to produce a schema and publish it to GitHub. The schema will be the starting point of our reference documentation.",
"wrap": true
},
{
"type": "FactSet",
"facts": [
{
"title": "Board:",
"value": "Adaptive Card"
},
{
"title": "List:",
"value": "Backlog"
},
{
"title": "Assigned to:",
"value": "Matt Hidinger"
},
{
"title": "Due date:",
"value": "Not set"
}
]
}
]
},
{
"type": "Input.Text",
"id": "debugText",
"isMultiline": true,
"placeholder": "This is a text box"
}
],
"actions": [
{
"type": "Action.ShowCard",
"title": "Comment",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"id": "comment",
"isMultiline": true,
"placeholder": "Enter your comment"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "OK"
}
]
}
},
{
"type": "Action.OpenUrl",
"title": "View",
"url": "https://adaptivecards.io"
}
]
})"
};
winrt::hstring semiAdvancedCard{
LR"({
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Publish Adaptive Card schema",
"weight": "bolder",
"size": "medium"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg",
"size": "small",
"style": "person"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Matt Hidinger",
"weight": "bolder",
"wrap": true
},
{
"type": "TextBlock",
"spacing": "none",
"text": "Created {{DATE(2017-02-14T06:08:39Z, SHORT)}}",
"isSubtle": true,
"wrap": true
}
]
}
]
},
{
"type": "TextBlock",
"text": "Now that we have defined the main rules and features of the format, we need to produce a schema and publish it to GitHub. The schema will be the starting point of our reference documentation.",
"wrap": true
},
{
"type": "Input.Text",
"id": "comment",
"isMultiline": true,
"placeholder": "Enter your comment"
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "OK"
},
{
"type": "Action.OpenUrl",
"title": "View",
"url": "https://adaptivecards.io"
}
]
})"
};
void TerminalPage::_HandleHacktion(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
const auto focusedTab{ _GetFocusedTabImpl() };
// Do nothing if no TerminalTab is focused
if (!focusedTab)
{
return;
}
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
const winrt::Windows::Foundation::Size availableSpace{ contentWidth, contentHeight };
const auto realSplitType = focusedTab->PreCalculateAutoSplit(availableSpace);
const float splitSize{ .5f };
auto content{ winrt::make_self<implementation::AdaptiveCardContent>() };
winrt::hstring json{ advancedCard };
try
{
struct __declspec(uuid("76b3f18c-89ed-4a29-98ac-2096395e7c32")) hack
{
};
winrt::guid g{ __uuidof(hack) };
auto iCard = winrt::create_instance<winrt::CardExtension::ICardExtension>(g);
if (iCard)
{
json = iCard.GetJson();
}
}
CATCH_LOG();
content->InitFromString(json);
// Windows::UI::Xaml::Controls::TextBox box{};
// // box.TextWrapping("Wrap" )
// box.AcceptsReturn(true);
// box.IsSpellCheckEnabled(true);
// Windows::UI::Xaml::Controls::Control c{ box };
// AdaptiveCardRenderer renderer{};
// winrt::hstring jsonString{ advancedCard };
// auto card{ winrt::AdaptiveCards::Rendering::Uwp::AdaptiveCard::FromJsonString(jsonString) };
// // Alternatively:
// // var card = AdaptiveCard.FromJson(jsonObject);
// RenderedAdaptiveCard renderedAdaptiveCard{ renderer.RenderAdaptiveCard(card.AdaptiveCard()) };
// _cards.Append(renderedAdaptiveCard);
// const auto fwe{ renderedAdaptiveCard.FrameworkElement() };
// Windows::UI::Xaml::Controls::Grid g{};
// g.HorizontalAlignment(Windows::UI::Xaml::HorizontalAlignment::Stretch);
// g.VerticalAlignment(Windows::UI::Xaml::VerticalAlignment::Stretch);
// g.Children().Append(renderedAdaptiveCard.FrameworkElement());
// g.RequestedTheme(_settings.GlobalSettings().Theme());
focusedTab->SplitPane(realSplitType, splitSize, *content);
args.Handled(true);
}
}

View file

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.CardExtension
{
interface ICardExtension
{
String GetJson();
};
}

View file

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
interface IPaneContent
{
Windows.UI.Xaml.FrameworkElement GetRoot();
Windows.Foundation.Size MinSize { get; };
void Focus();
void Close();
Microsoft.Terminal.Settings.Model.NewTerminalArgs GetTerminalArgsForPane();
// event CloseRequested(...);
};
}

View file

@ -5,7 +5,7 @@
#include "Pane.h"
#include "AppLogic.h"
#include <Mmsystem.h>
// #include <Mmsystem.h>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Graphics::Display;
@ -34,16 +34,12 @@ static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Wi
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr };
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr };
Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFocused) :
_control{ control },
_lastActive{ lastFocused },
_profile{ profile }
Pane::Pane(const IPaneContent& content, const bool lastFocused) :
_content{ content },
_lastActive{ lastFocused }
{
_root.Children().Append(_borderFirst);
_borderFirst.Child(_control);
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
_borderFirst.Child(content.GetRoot());
// On the first Pane's creation, lookup resources we'll use to theme the
// Pane, including the brushed to use for the focused/unfocused border
@ -54,8 +50,12 @@ Pane::Pane(const Profile& profile, const TermControl& control, const bool lastFo
}
// Register an event with the control to have it inform us when it gains focus.
_gotFocusRevoker = _control.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = _control.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
// TODO!: _content.GetRoot() seems wrong
if (const auto c{ _content.GetRoot().try_as<Controls::Control>() })
{
_gotFocusRevoker = c.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = c.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
}
// When our border is tapped, make sure to transfer focus to our control.
// LOAD-BEARING: This will NOT work if the border's BorderBrush is set to
@ -123,51 +123,7 @@ NewTerminalArgs Pane::GetTerminalArgsForPane() const
{
// Leaves are the only things that have controls
assert(_IsLeaf());
NewTerminalArgs args{};
auto controlSettings = _control.Settings().as<TerminalSettings>();
args.Profile(controlSettings.ProfileName());
// If we know the user's working directory use it instead of the profile.
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
{
args.StartingDirectory(dir);
}
else
{
args.StartingDirectory(controlSettings.StartingDirectory());
}
args.TabTitle(controlSettings.StartingTitle());
args.Commandline(controlSettings.Commandline());
args.SuppressApplicationTitle(controlSettings.SuppressApplicationTitle());
if (controlSettings.TabColor() || controlSettings.StartingTabColor())
{
til::color c;
// StartingTabColor is prioritized over other colors
if (const auto color = controlSettings.StartingTabColor())
{
c = til::color(color.Value());
}
else
{
c = til::color(controlSettings.TabColor().Value());
}
args.TabColor(winrt::Windows::Foundation::IReference<winrt::Windows::UI::Color>(c));
}
if (controlSettings.AppliedColorScheme())
{
auto name = controlSettings.AppliedColorScheme().Name();
// Only save the color scheme if it is different than the profile color
// scheme to not override any other profile appearance choices.
if (_profile.DefaultAppearance().ColorSchemeName() != name)
{
args.ColorScheme(name);
}
}
return args;
return _content.GetTerminalArgsForPane();
}
// Method Description:
@ -1067,45 +1023,49 @@ Pane::PaneNeighborSearch Pane::_FindPaneAndNeighbor(const std::shared_ptr<Pane>
void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
std::unique_lock lock{ _createCloseLock };
// It's possible that this event handler started being executed, then before
// we got the lock, another thread created another child. So our control is
// actually no longer _our_ control, and instead could be a descendant.
//
// When the control's new Pane takes ownership of the control, the new
// parent will register it's own event handler. That event handler will get
// fired after this handler returns, and will properly cleanup state.
if (!_IsLeaf())
{
return;
}
// std::unique_lock lock{ _createCloseLock };
// // It's possible that this event handler started being executed, then before
// // we got the lock, another thread created another child. So our control is
// // actually no longer _our_ control, and instead could be a descendant.
// //
// // When the control's new Pane takes ownership of the control, the new
// // parent will register it's own event handler. That event handler will get
// // fired after this handler returns, and will properly cleanup state.
// if (!_IsLeaf())
// {
// return;
// }
// const auto& termControl{ _control.try_as<TermControl>() };
// if (!termControl)
// {
// return;
// }
// const auto newConnectionState = termControl.ConnectionState();
// const auto previousConnectionState = std::exchange(_connectionState, newConnectionState);
const auto newConnectionState = _control.ConnectionState();
const auto previousConnectionState = std::exchange(_connectionState, newConnectionState);
// if (newConnectionState < ConnectionState::Closed)
// {
// // Pane doesn't care if the connection isn't entering a terminal state.
// return;
// }
if (newConnectionState < ConnectionState::Closed)
{
// Pane doesn't care if the connection isn't entering a terminal state.
return;
}
// if (previousConnectionState < ConnectionState::Connected && newConnectionState >= ConnectionState::Failed)
// {
// // A failure to complete the connection (before it has _connected_) is not covered by "closeOnExit".
// // This is to prevent a misconfiguration (closeOnExit: always, startingDirectory: garbage) resulting
// // in Terminal flashing open and immediately closed.
// return;
// }
if (previousConnectionState < ConnectionState::Connected && newConnectionState >= ConnectionState::Failed)
{
// A failure to complete the connection (before it has _connected_) is not covered by "closeOnExit".
// This is to prevent a misconfiguration (closeOnExit: always, startingDirectory: garbage) resulting
// in Terminal flashing open and immediately closed.
return;
}
if (_profile)
{
const auto mode = _profile.CloseOnExit();
if ((mode == CloseOnExitMode::Always) ||
(mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
{
Close();
}
}
// if (_profile)
// {
// const auto mode = _profile.CloseOnExit();
// if ((mode == CloseOnExitMode::Always) ||
// (mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
// {
// Close();
// }
// }
}
// Method Description:
@ -1119,31 +1079,33 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio
void Pane::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
if (!_IsLeaf())
{
return;
}
if (_profile)
{
// We don't want to do anything if nothing is set, so check for that first
if (static_cast<int>(_profile.BellStyle()) != 0)
{
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
{
// Audible is set, play the sound
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
// if (!_IsLeaf())
// {
// return;
// }
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
{
_control.BellLightOn();
}
// const auto& termControl{ _control.try_as<TermControl>() };
// if (_profile && termControl)
// {
// // We don't want to do anything if nothing is set, so check for that first
// if (static_cast<int>(_profile.BellStyle()) != 0)
// {
// if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
// {
// // Audible is set, play the sound
// const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
// PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
// }
// raise the event with the bool value corresponding to the taskbar flag
_PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
}
}
// if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
// {
// termControl.BellLightOn();
// }
// // raise the event with the bool value corresponding to the taskbar flag
// _PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
// }
// }
}
// Event Description:
@ -1197,7 +1159,12 @@ void Pane::Shutdown()
std::unique_lock lock{ _createCloseLock };
if (_IsLeaf())
{
_control.Close();
_content.Close();
/*const auto& termControl{ _control.try_as<TermControl>() };
if (termControl)
{
termControl.Close();
}*/
}
else
{
@ -1207,7 +1174,7 @@ void Pane::Shutdown()
}
// Method Description:
// - Get the root UIElement of this pane. There may be a single TermControl as a
// - Get the root UIElement of this pane. There may be a single FrameworkElement as a
// child, or an entire tree of grids and panes as children of this element.
// Arguments:
// - <none>
@ -1266,7 +1233,7 @@ TermControl Pane::GetLastFocusedTerminalControl()
{
if (p->_IsLeaf())
{
return p->_control;
return p->GetTerminalControl();
}
pane = p;
}
@ -1274,7 +1241,7 @@ TermControl Pane::GetLastFocusedTerminalControl()
}
return _firstChild->GetLastFocusedTerminalControl();
}
return _control;
return GetTerminalControl();
}
// Method Description:
@ -1283,10 +1250,12 @@ TermControl Pane::GetLastFocusedTerminalControl()
// Arguments:
// - <none>
// Return Value:
// - nullptr if this Pane is a parent, otherwise the TermControl of this Pane.
TermControl Pane::GetTerminalControl()
// - nullptr if this Pane is a parent or isn't hosting a Terminal, otherwise the
// TermControl of this Pane.
TermControl Pane::GetTerminalControl() const
{
return _IsLeaf() ? _control : nullptr;
// TODO! this feels like a hack, the Pane shouldn't know this
return _IsLeaf() ? _content.GetRoot().try_as<TermControl>() : nullptr;
}
// Method Description:
@ -1333,7 +1302,17 @@ void Pane::SetActive()
Profile Pane::GetFocusedProfile()
{
auto lastFocused = GetActivePane();
return lastFocused ? lastFocused->_profile : nullptr;
if (!lastFocused)
{
return nullptr;
}
// TODO! again dirty
if (const auto& terminalContent{ lastFocused->_content.try_as<TerminalPaneContent>() })
{
return terminalContent.GetProfile();
}
return nullptr;
// return lastFocused ? lastFocused->_profile : nullptr;
}
// Method Description:
@ -1405,6 +1384,7 @@ void Pane::UpdateVisuals()
void Pane::_Focus()
{
_GotFocusHandlers(shared_from_this(), FocusState::Programmatic);
// TODO!: this may be wrong
if (const auto& control = GetLastFocusedTerminalControl())
{
control.Focus(FocusState::Programmatic);
@ -1457,23 +1437,10 @@ void Pane::_FocusFirstChild()
void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const Profile& profile)
{
assert(_IsLeaf());
_profile = profile;
auto controlSettings = _control.Settings().as<TerminalSettings>();
// Update the parent of the control's settings object (and not the object itself) so
// that any overrides made by the control don't get affected by the reload
controlSettings.SetParent(settings.DefaultSettings());
auto unfocusedSettings{ settings.UnfocusedSettings() };
if (unfocusedSettings)
if (const auto& terminal{ _content.try_as<TerminalPaneContent>() })
{
// Note: the unfocused settings needs to be entirely unchanged _except_ we need to
// set its parent to the settings object that lives in the control. This is because
// the overrides made by the control live in that settings object, so we want to make
// sure the unfocused settings inherit from that.
unfocusedSettings.SetParent(controlSettings);
terminal.UpdateSettings(settings, profile);
}
_control.UnfocusedAppearance(unfocusedSettings);
_control.UpdateSettings();
}
// Method Description:
@ -1608,15 +1575,9 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
_borders = _GetCommonBorders();
// take the control, profile and id of the pane that _wasn't_ closed.
_control = remainingChild->_control;
_connectionState = remainingChild->_connectionState;
_profile = remainingChild->_profile;
_content = remainingChild->_content;
_id = remainingChild->Id();
// Add our new event handler before revoking the old one.
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
_warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler });
// Revoke the old event handlers. Remove both the handlers for the panes
// themselves closing, and remove their handlers for their controls
// closing. At this point, if the remaining child's control is closed,
@ -1629,8 +1590,7 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
closedChild->WalkTree([](auto p) {
if (p->_IsLeaf())
{
p->_control.ConnectionStateChanged(p->_connectionStateChangedToken);
p->_control.WarningBell(p->_warningBellToken);
p->_content.Close();
}
return false;
});
@ -1638,15 +1598,13 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
closedChild->Closed(closedChildClosedToken);
remainingChild->Closed(remainingChildClosedToken);
remainingChild->_control.ConnectionStateChanged(remainingChild->_connectionStateChangedToken);
remainingChild->_control.WarningBell(remainingChild->_warningBellToken);
// If we or either of our children was focused, we want to take that
// focus from them.
_lastActive = _lastActive || _firstChild->_lastActive || _secondChild->_lastActive;
// Remove all the ui elements of the remaining child. This'll make sure
// we can re-attach the TermControl to our Grid.
// we can re-attach the FrameworkElement to our Grid.
remainingChild->_root.Children().Clear();
remainingChild->_borderFirst.Child(nullptr);
@ -1657,9 +1615,9 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
_root.ColumnDefinitions().Clear();
_root.RowDefinitions().Clear();
// Reattach the TermControl to our grid.
// Reattach the FrameworkElement to our grid.
_root.Children().Append(_borderFirst);
_borderFirst.Child(_control);
_borderFirst.Child(_content.GetRoot());
// Make sure to set our _splitState before focusing the control. If you
// fail to do this, when the tab handles the GotFocus event and asks us
@ -1668,14 +1626,23 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
_splitState = SplitState::None;
// re-attach our handler for the control's GotFocus event.
_gotFocusRevoker = _control.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = _control.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
// TODO!: _content.GetRoot() seems wrong
if (const auto c{ _content.GetRoot().try_as<Controls::Control>() })
{
_gotFocusRevoker = c.GotFocus(winrt::auto_revoke, { this, &Pane::_ControlGotFocusHandler });
_lostFocusRevoker = c.LostFocus(winrt::auto_revoke, { this, &Pane::_ControlLostFocusHandler });
}
// If we're inheriting the "last active" state from one of our children,
// focus our control now. This should trigger our own GotFocus event.
if (usedToFocusClosedChildsTerminal || _lastActive)
{
_control.Focus(FocusState::Programmatic);
// TODO!: _content.GetRoot() seems wrong
if (const auto c{ _content.GetRoot().try_as<Controls::Control>() })
{
c.Focus(FocusState::Programmatic);
}
// See GH#7252
// Manually fire off the GotFocus event. Typically, this is done
@ -1719,8 +1686,7 @@ void Pane::_CloseChild(const bool closeFirst, const bool isDetaching)
closedChild->WalkTree([](auto p) {
if (p->_IsLeaf())
{
p->_control.ConnectionStateChanged(p->_connectionStateChangedToken);
p->_control.WarningBell(p->_warningBellToken);
p->_content.Close();
}
return false;
});
@ -2147,7 +2113,7 @@ void Pane::_SetupEntranceAnimation()
auto child = isFirstChild ? _firstChild : _secondChild;
auto childGrid = child->_root;
// If we are splitting a parent pane this may be null
auto control = child->_control;
auto control = child->_content.GetRoot();
// Build up our animation:
// * it'll take as long as our duration (200ms)
// * it'll change the value of our property from 0 to secondSize
@ -2352,34 +2318,33 @@ std::optional<bool> Pane::PreCalculateCanSplit(const std::shared_ptr<Pane> targe
// Method Description:
// - Split the focused pane in our tree of panes, and place the given
// TermControl into the newly created pane. If we're the focused pane, then
// FrameworkElement into the newly created pane. If we're the focused pane, then
// we'll create two new children, and place them side-by-side in our Grid.
// Arguments:
// - splitType: what type of split we want to create.
// - profile: The profile to associate with the newly created pane.
// - control: A TermControl to use in the new pane.
// - control: A FrameworkElement to use in the new pane.
// Return Value:
// - The two newly created Panes, with the original pane first
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::Split(SplitDirection splitType,
const float splitSize,
const Profile& profile,
const TermControl& control)
const IPaneContent& content)
{
if (!_lastActive)
{
if (_firstChild && _firstChild->_HasFocusedChild())
{
return _firstChild->Split(splitType, splitSize, profile, control);
return _firstChild->Split(splitType, splitSize, content);
}
else if (_secondChild && _secondChild->_HasFocusedChild())
{
return _secondChild->Split(splitType, splitSize, profile, control);
return _secondChild->Split(splitType, splitSize, content);
}
return { nullptr, nullptr };
}
auto newPane = std::make_shared<Pane>(profile, control);
auto newPane = std::make_shared<Pane>(content);
return _Split(splitType, splitSize, newPane);
}
@ -2471,11 +2436,14 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
if (_IsLeaf())
{
// revoke our handler - the child will take care of the control now.
_control.ConnectionStateChanged(_connectionStateChangedToken);
_connectionStateChangedToken.value = 0;
_control.WarningBell(_warningBellToken);
_warningBellToken.value = 0;
// if (const auto& termControl{ _control.try_as<TermControl>() })
// {
// // revoke our handler - the child will take care of the control now.
// termControl.ConnectionStateChanged(_connectionStateChangedToken);
// _connectionStateChangedToken.value = 0;
// termControl.WarningBell(_warningBellToken);
// _warningBellToken.value = 0;
// }
// Remove our old GotFocus handler from the control. We don't want the
// control telling us that it's now focused, we want it telling its new
@ -2485,7 +2453,7 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
}
// Remove any children we currently have. We can't add the existing
// TermControl to a new grid until we do this.
// FrameworkElement to a new grid until we do this.
_root.Children().Clear();
_borderFirst.Child(nullptr);
_borderSecond.Child(nullptr);
@ -2505,10 +2473,10 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
else
{
// Move our control, guid into the first one.
_firstChild = std::make_shared<Pane>(_profile, _control);
_firstChild->_connectionState = std::exchange(_connectionState, ConnectionState::NotConnected);
_profile = nullptr;
_control = { nullptr };
_firstChild = std::make_shared<Pane>(_content);
// _firstChild->_connectionState = std::exchange(_connectionState, ConnectionState::NotConnected);
// _profile = nullptr;
_content = { nullptr };
}
_splitState = actualSplitType;
@ -2865,6 +2833,12 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
{
if (_IsLeaf())
{
// TODO!: Again, bad. We're special-casing that the content just so happens to have a TermControl
const auto& termControl{ _content.GetRoot().try_as<TermControl>() };
if (!termControl)
{
return { dimension, dimension };
}
// If we're a leaf pane, align to the grid of controlling terminal
const auto minSize = _GetMinSize();
@ -2875,7 +2849,7 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
return { minDimension, minDimension };
}
float lower = _control.SnapDimensionToGrid(widthOrHeight, dimension);
float lower = termControl.SnapDimensionToGrid(widthOrHeight, dimension);
if (widthOrHeight)
{
lower += WI_IsFlagSet(_borders, Borders::Left) ? PaneBorderSize : 0;
@ -2895,7 +2869,7 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
}
else
{
const auto cellSize = _control.CharacterDimensions();
const auto cellSize = termControl.CharacterDimensions();
const auto higher = lower + (widthOrHeight ? cellSize.Width : cellSize.Height);
return { lower, higher };
}
@ -2942,24 +2916,38 @@ void Pane::_AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& si
{
if (_IsLeaf())
{
// We're a leaf pane, so just add one more row or column (unless isMinimumSize
// is true, see below).
if (sizeNode.isMinimumSize)
// TODO!: Again, bad. We're special-casing that the content just so happens to have a TermControl
const auto& termControl{ _content.GetRoot().try_as<TermControl>() };
if (termControl)
{
// If the node is of its minimum size, this size might not be snapped (it might
// be, say, half a character, or fixed 10 pixels), so snap it upward. It might
// however be already snapped, so add 1 to make sure it really increases
// (not strictly necessary but to avoid surprises).
sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher;
// We're a leaf pane, so just add one more row or column (unless isMinimumSize
// is true, see below).
if (sizeNode.isMinimumSize)
{
// If the node is of its minimum size, this size might not be snapped (it might
// be, say, half a character, or fixed 10 pixels), so snap it upward. It might
// however be already snapped, so add 1 to make sure it really increases
// (not strictly necessary but to avoid surprises).
sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher;
}
else
{
const auto cellSize = termControl.CharacterDimensions();
sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height;
}
}
else
{
const auto cellSize = _control.CharacterDimensions();
sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height;
// If we're a leaf that didn't have a TermControl, then just increment
// by one. We have to increment by _some_ value, because this is used in
// a while() loop to find the next bigger size we can snap to. But since
// a non-terminal control doesn't really care what size it's snapped to,
// we can just say "one pixel larger is the next snap point"
sizeNode.size += 1;
}
}
else
else if (!_IsLeaf())
{
// We're a parent pane, so we have to advance dimension of our children panes. In
// fact, we advance only one child (chosen later) to keep the growth fine-grained.
@ -3061,7 +3049,8 @@ Size Pane::_GetMinSize() const
{
if (_IsLeaf())
{
auto controlSize = _control.MinimumSize();
// const auto& termControl{ _control.try_as<TermControl>() };
auto controlSize = _content.MinSize(); // termControl ? termControl.MinimumSize() : Size{ 1, 1 };
auto newWidth = controlSize.Width;
auto newHeight = controlSize.Height;
@ -3247,7 +3236,10 @@ std::optional<SplitDirection> Pane::PreCalculateAutoSplit(const std::shared_ptr<
// - Returns true if the pane or one of its descendants is read-only
bool Pane::ContainsReadOnly() const
{
return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
const auto& termControl{ GetTerminalControl() };
return termControl ?
termControl.ReadOnly() :
(_IsLeaf() ? false : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly()));
}
// Method Description:
@ -3260,13 +3252,14 @@ bool Pane::ContainsReadOnly() const
// - <none>
void Pane::CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states)
{
if (_IsLeaf())
const auto& termControl{ GetTerminalControl() };
if (termControl)
{
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(_control.TaskbarState(),
_control.TaskbarProgress()) };
auto tbState{ winrt::make<winrt::TerminalApp::implementation::TaskbarState>(termControl.TaskbarState(),
termControl.TaskbarProgress()) };
states.push_back(tbState);
}
else
else if (!_IsLeaf())
{
_firstChild->CollectTaskbarStates(states);
_secondChild->CollectTaskbarStates(states);

View file

@ -22,6 +22,7 @@
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "TaskbarState.h"
#include "TerminalPaneContent.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
@ -55,8 +56,7 @@ enum class SplitState : int
class Pane : public std::enable_shared_from_this<Pane>
{
public:
Pane(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control,
Pane(const winrt::TerminalApp::IPaneContent& content,
const bool lastFocused = false);
Pane(std::shared_ptr<Pane> first,
@ -66,16 +66,21 @@ public:
const bool lastFocused = false);
std::shared_ptr<Pane> GetActivePane();
winrt::Microsoft::Terminal::Control::TermControl GetLastFocusedTerminalControl();
winrt::Microsoft::Terminal::Control::TermControl GetTerminalControl();
// winrt::Windows::UI::Xaml::FrameworkElement GetControl() const;
winrt::Microsoft::Terminal::Control::TermControl GetTerminalControl() const;
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile();
winrt::Microsoft::Terminal::Control::TermControl GetLastFocusedTerminalControl();
// Method Description:
// - If this is a leaf pane, return its profile.
// - If this is a branch/root pane, return nullptr.
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
{
return _profile;
if (const auto& c{ _content.try_as<winrt::TerminalApp::TerminalPaneContent>() })
{
return c.GetProfile();
}
return nullptr;
}
winrt::Windows::UI::Xaml::Controls::Grid GetRootElement();
@ -110,8 +115,7 @@ public:
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control);
const winrt::TerminalApp::IPaneContent& content);
bool ToggleSplitOrientation();
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateAutoSplit(const std::shared_ptr<Pane> target,
@ -201,8 +205,9 @@ private:
winrt::Windows::UI::Xaml::Controls::Grid _root{};
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
winrt::TerminalApp::IPaneContent _content{ nullptr };
// winrt::Windows::UI::Xaml::FrameworkElement _control{ nullptr };
// winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_focusedBorderBrush;
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_unfocusedBorderBrush;
@ -215,11 +220,11 @@ private:
std::weak_ptr<Pane> _parentChildPath{};
bool _lastActive{ false };
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
winrt::event_token _connectionStateChangedToken{ 0 };
// winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
// winrt::event_token _connectionStateChangedToken{ 0 };
winrt::event_token _firstClosedToken{ 0 };
winrt::event_token _secondClosedToken{ 0 };
winrt::event_token _warningBellToken{ 0 };
// winrt::event_token _warningBellToken{ 0 };
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
@ -263,7 +268,8 @@ private:
void _Focus();
void _FocusFirstChild();
void _ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& /*args*/);
void _ControlWarningBellHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::Foundation::IInspectable const& e);
void _ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,

View file

@ -51,7 +51,7 @@ namespace winrt
namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Open a new tab. This will create the TerminalControl hosting the
// - Open a new tab. This will create the TerminalControl Control hosting the
// terminal, and add a new Tab to our list of tabs. The method can
// optionally be provided a NewTerminalArgs, which will be used to create
// a tab using the values in that object.
@ -282,8 +282,8 @@ namespace winrt::TerminalApp::implementation
// Give term control a child of the settings so that any overrides go in the child
// This way, when we do a settings reload we just update the parent and the overrides remain
auto term = _InitControl(settings, connection);
auto newTabImpl = winrt::make_self<TerminalTab>(profile, term);
auto content{ winrt::make<TerminalPaneContent>(profile, term) };
auto newTabImpl = winrt::make_self<TerminalTab>(content);
_RegisterTerminalEvents(term);
_InitializeTab(newTabImpl);
@ -292,7 +292,8 @@ namespace winrt::TerminalApp::implementation
auto newControl = _InitControl(settings, debugConnection);
_RegisterTerminalEvents(newControl);
// Split (auto) with the debug tap.
newTabImpl->SplitPane(SplitDirection::Automatic, 0.5f, profile, newControl);
auto content{ winrt::make<TerminalPaneContent>(profile, newControl) };
newTabImpl->SplitPane(SplitDirection::Automatic, 0.5f, content);
}
}

View file

@ -141,6 +141,12 @@
<ClInclude Include="AppLogic.h">
<DependentUpon>AppLogic.idl</DependentUpon>
</ClInclude>
<ClInclude Include="AdaptiveCardContent.h">
<DependentUpon>AdaptiveCardContent.idl</DependentUpon>
</ClInclude>
<ClInclude Include="TerminalPaneContent.h">
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Toast.h" />
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
@ -234,6 +240,12 @@
<ClCompile Include="AppLogic.cpp">
<DependentUpon>AppLogic.idl</DependentUpon>
</ClCompile>
<ClCompile Include="AdaptiveCardContent.cpp">
<DependentUpon>AdaptiveCardContent.idl</DependentUpon>
</ClCompile>
<ClCompile Include="TerminalPaneContent.cpp">
<DependentUpon>TerminalPaneContent.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="Toast.cpp" />
</ItemGroup>
@ -255,6 +267,9 @@
<Midl Include="ShortcutActionDispatch.idl" />
<Midl Include="AppKeyBindings.idl" />
<Midl Include="AppLogic.idl" />
<Midl Include="AdaptiveCardContent.idl" />
<Midl Include="TerminalPaneContent.idl" />
<Midl Include="IPaneContent.idl" />
<Midl Include="MinMaxCloseControl.idl">
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
<SubType>Code</SubType>
@ -361,6 +376,12 @@
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.CardExtension">
<HintPath>$(SolutionDir)\$(Platform)\$(Configuration)\ICardExtension\Microsoft.CardExtension.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
</ItemGroup>
<!-- ====================== Compiler & Linker Flags ===================== -->
<ItemDefinitionGroup>
@ -376,9 +397,10 @@
</ItemDefinitionGroup>
<!-- ========================= Globals ======================== -->
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Import Project="..\..\..\packages\AdaptiveCards.Rendering.Uwp.2.7.0\build\native\AdaptiveCards.Rendering.Uwp.targets" Condition="Exists('..\..\..\packages\AdaptiveCards.Rendering.Uwp.2.7.0\build\native\AdaptiveCards.Rendering.Uwp.targets')" />
<Import Project="..\..\..\packages\AdaptiveCards.ObjectModel.Uwp.1.0.0\build\native\AdaptiveCards.ObjectModel.Uwp.targets" Condition="Exists('..\..\..\packages\AdaptiveCards.ObjectModel.Uwp.1.0.0\build\native\AdaptiveCards.ObjectModel.Uwp.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>
@ -386,6 +408,8 @@
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\AdaptiveCards.Rendering.Uwp.2.7.0\build\native\AdaptiveCards.Rendering.Uwp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\AdaptiveCards.Rendering.Uwp.2.7.0\build\native\AdaptiveCards.Rendering.Uwp.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\AdaptiveCards.ObjectModel.Uwp.1.0.0\build\native\AdaptiveCards.ObjectModel.Uwp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\AdaptiveCards.ObjectModel.Uwp.1.0.0\build\native\AdaptiveCards.ObjectModel.Uwp.targets'))" />
</Target>
<!--
By default, the PRI file will contain resource paths beginning with the

View file

@ -21,9 +21,6 @@
<ClCompile Include="ColorHelper.cpp" />
<ClCompile Include="DebugTapConnection.cpp" />
<ClCompile Include="Jumplist.cpp" />
<ClCompile Include="Tab.cpp">
<Filter>tab</Filter>
</ClCompile>
<ClCompile Include="SettingsTab.cpp">
<Filter>tab</Filter>
</ClCompile>
@ -61,9 +58,6 @@
<ClInclude Include="DebugTapConnection.h" />
<ClInclude Include="ColorHelper.h" />
<ClInclude Include="Jumplist.h" />
<ClInclude Include="Tab.h">
<Filter>tab</Filter>
</ClInclude>
<ClInclude Include="SettingsTab.h">
<Filter>tab</Filter>
</ClInclude>
@ -117,6 +111,10 @@
<Midl Include="PaletteItemTemplateSelector.idl" />
<Midl Include="TabBase.idl" />
<Midl Include="EmptyStringVisibilityConverter.idl" />
<Midl Include="AdaptiveCardContent.idl" />
<Midl Include="TerminalPaneContent.idl" />
<Midl Include="IPaneContent.idl" />
<Midl Include="TaskbarState.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -1588,14 +1588,18 @@ namespace winrt::TerminalApp::implementation
_UnZoomIfNeeded();
tab.SplitPane(realSplitType, splitSize, profile, newControl);
auto content{ winrt::make<TerminalPaneContent>(profile, newControl) };
tab.SplitPane(realSplitType, splitSize, content);
// After GH#6586, the control will no longer focus itself
// automatically when it's finished being laid out. Manually focus
// the control here instead.
if (_startupState == StartupState::Initialized)
{
_GetActiveControl().Focus(FocusState::Programmatic);
if (const auto& activeControl{ _GetActiveControl() })
{
activeControl.Focus(FocusState::Programmatic);
}
}
}
CATCH_LOG();

View file

@ -0,0 +1,203 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "TerminalPaneContent.h"
#include "TerminalPaneContent.g.cpp"
#include <Mmsystem.h>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
using namespace winrt::Microsoft::Terminal::TerminalConnection;
namespace winrt::TerminalApp::implementation
{
TerminalPaneContent::TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control) :
_control{ control },
_profile{ profile }
{
_connectionStateChangedToken = control.ConnectionStateChanged({ this, &TerminalPaneContent::_ControlConnectionStateChangedHandler });
_warningBellToken = control.WarningBell({ this, &TerminalPaneContent::_ControlWarningBellHandler });
}
winrt::Windows::UI::Xaml::FrameworkElement TerminalPaneContent::GetRoot()
{
return _control;
}
winrt::Microsoft::Terminal::Control::TermControl TerminalPaneContent::GetTerminal()
{
return _control;
}
winrt::Windows::Foundation::Size TerminalPaneContent::MinSize()
{
return _control.MinimumSize();
}
void TerminalPaneContent::Focus()
{
_control.Focus(FocusState::Programmatic);
}
void TerminalPaneContent::Close()
{
_control.ConnectionStateChanged(_connectionStateChangedToken);
_control.WarningBell(_warningBellToken);
}
// Method Description:
// - Called when our attached control is closed. Triggers listeners to our close
// event, if we're a leaf pane.
// - If this was called, and we became a parent pane (due to work on another
// thread), this function will do nothing (allowing the control's new parent
// to handle the event instead).
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPaneContent::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
const auto newConnectionState = _control.ConnectionState();
const auto previousConnectionState = std::exchange(_connectionState, newConnectionState);
if (newConnectionState < ConnectionState::Closed)
{
// Pane doesn't care if the connection isn't entering a terminal state.
return;
}
if (previousConnectionState < ConnectionState::Connected &&
newConnectionState >= ConnectionState::Failed)
{
// A failure to complete the connection (before it has _connected_) is not covered by "closeOnExit".
// This is to prevent a misconfiguration (closeOnExit: always, startingDirectory: garbage) resulting
// in Terminal flashing open and immediately closed.
return;
}
if (_profile)
{
const auto mode = _profile.CloseOnExit();
if ((mode == CloseOnExitMode::Always) ||
(mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed))
{
// TODO!
// _CloseRequestedHandlers(*this, nullptr);
}
}
}
// Method Description:
// - Plays a warning note when triggered by the BEL control character,
// using the sound configured for the "Critical Stop" system event.`
// This matches the behavior of the Windows Console host.
// - Will also flash the taskbar if the bellStyle setting for this profile
// has the 'visual' flag set
// Arguments:
// - <unused>
void TerminalPaneContent::_ControlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
if (_profile)
{
// We don't want to do anything if nothing is set, so check for that first
if (static_cast<int>(_profile.BellStyle()) != 0)
{
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
{
// Audible is set, play the sound
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
{
_control.BellLightOn();
}
// raise the event with the bool value corresponding to the taskbar flag
// TODO!
// _PaneRaiseBellHandlers(nullptr, WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Taskbar));
}
}
}
void TerminalPaneContent::UpdateSettings(const TerminalSettingsCreateResult& settings,
const Profile& profile)
{
_profile = profile;
auto controlSettings = _control.Settings().as<TerminalSettings>();
// Update the parent of the control's settings object (and not the object itself) so
// that any overrides made by the control don't get affected by the reload
controlSettings.SetParent(settings.DefaultSettings());
auto unfocusedSettings{ settings.UnfocusedSettings() };
if (unfocusedSettings)
{
// Note: the unfocused settings needs to be entirely unchanged _except_ we need to
// set its parent to the settings object that lives in the control. This is because
// the overrides made by the control live in that settings object, so we want to make
// sure the unfocused settings inherit from that.
unfocusedSettings.SetParent(controlSettings);
}
_control.UnfocusedAppearance(unfocusedSettings);
_control.UpdateSettings();
}
// Method Description:
// - Extract the terminal settings from the current (leaf) pane's control
// to be used to create an equivalent control
// Arguments:
// - <none>
// Return Value:
// - Arguments appropriate for a SplitPane or NewTab action
NewTerminalArgs TerminalPaneContent::GetTerminalArgsForPane() const
{
NewTerminalArgs args{};
auto controlSettings = _control.Settings().as<TerminalSettings>();
args.Profile(controlSettings.ProfileName());
// If we know the user's working directory use it instead of the profile.
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
{
args.StartingDirectory(dir);
}
else
{
args.StartingDirectory(controlSettings.StartingDirectory());
}
args.TabTitle(controlSettings.StartingTitle());
args.Commandline(controlSettings.Commandline());
args.SuppressApplicationTitle(controlSettings.SuppressApplicationTitle());
if (controlSettings.TabColor() || controlSettings.StartingTabColor())
{
til::color c;
// StartingTabColor is prioritized over other colors
if (const auto color = controlSettings.StartingTabColor())
{
c = til::color(color.Value());
}
else
{
c = til::color(controlSettings.TabColor().Value());
}
args.TabColor(winrt::Windows::Foundation::IReference<winrt::Windows::UI::Color>(c));
}
if (controlSettings.AppliedColorScheme())
{
auto name = controlSettings.AppliedColorScheme().Name();
// Only save the color scheme if it is different than the profile color
// scheme to not override any other profile appearance choices.
if (_profile.DefaultAppearance().ColorSchemeName() != name)
{
args.ColorScheme(name);
}
}
return args;
}
}

View file

@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "TerminalPaneContent.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
struct TerminalPaneContent : TerminalPaneContentT<TerminalPaneContent>
{
TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
const winrt::Microsoft::Terminal::Control::TermControl& control);
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
winrt::Microsoft::Terminal::Control::TermControl GetTerminal();
winrt::Windows::Foundation::Size MinSize();
void Focus();
void Close();
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
{
return _profile;
};
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane() const;
private:
winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr };
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
winrt::event_token _connectionStateChangedToken{ 0 };
winrt::event_token _warningBellToken{ 0 };
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
void _ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& /*args*/);
void _ControlWarningBellHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::Foundation::IInspectable const& e);
};
}

View file

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "IPaneContent.idl";
namespace TerminalApp
{
[default_interface] runtimeclass TerminalPaneContent : IPaneContent
{
Microsoft.Terminal.Control.TermControl GetTerminal();
void UpdateSettings(const Microsoft.Terminal.Settings.Model.TerminalSettingsCreateResult settings,
const Microsoft.Terminal.Settings.Model.Profile profile);
Microsoft.Terminal.Settings.Model.Profile GetProfile();
}
}

View file

@ -25,9 +25,9 @@ namespace winrt
namespace winrt::TerminalApp::implementation
{
TerminalTab::TerminalTab(const Profile& profile, const TermControl& control)
TerminalTab::TerminalTab(const IPaneContent& content)
{
_rootPane = std::make_shared<Pane>(profile, control, true);
_rootPane = std::make_shared<Pane>(content, true);
_rootPane->Id(_nextPaneId);
_activePane = _rootPane;
@ -437,7 +437,10 @@ namespace winrt::TerminalApp::implementation
winrt::fire_and_forget TerminalTab::Scroll(const int delta)
{
auto control = GetActiveTerminalControl();
if (!control)
{
co_return;
}
co_await winrt::resume_foreground(control.Dispatcher());
const auto currentOffset = control.ScrollOffset();
@ -512,15 +515,14 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalTab::SplitPane(SplitDirection splitType,
const float splitSize,
const Profile& profile,
TermControl& control)
const IPaneContent& content)
{
// Make sure to take the ID before calling Split() - Split() will clear out the active pane's ID
const auto activePaneId = _activePane->Id();
// Depending on which direction will be split, the new pane can be
// either the first or second child, but this will always return the
// original pane first.
auto [original, newPane] = _activePane->Split(splitType, splitSize, profile, control);
auto [original, newPane] = _activePane->Split(splitType, splitSize, content);
// The active pane has an id if it is a leaf
if (activePaneId)
{
@ -533,7 +535,11 @@ namespace winrt::TerminalApp::implementation
// Add a event handlers to the new panes' GotFocus event. When the pane
// gains focus, we'll mark it as the new active pane.
_AttachEventHandlersToControl(newPane->Id().value(), control);
// TODO!: feels dirty
if (const auto& termControl{ content.GetRoot().try_as<TermControl>() })
{
_AttachEventHandlersToControl(newPane->Id().value(), termControl);
}
_AttachEventHandlersToPane(original);
_AttachEventHandlersToPane(newPane);
@ -1341,6 +1347,13 @@ namespace winrt::TerminalApp::implementation
// - The tab's color, if any
std::optional<winrt::Windows::UI::Color> TerminalTab::GetTabColor()
{
const auto& termControl{ GetActiveTerminalControl() };
if (!termControl)
{
return std::nullopt;
}
const auto currControlColor{ termControl.TabColor() };
std::optional<winrt::Windows::UI::Color> controlTabColor;
if (const auto& control = GetActiveTerminalControl())
{

View file

@ -21,7 +21,7 @@ namespace winrt::TerminalApp::implementation
struct TerminalTab : TerminalTabT<TerminalTab, TabBase>
{
public:
TerminalTab(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile, const winrt::Microsoft::Terminal::Control::TermControl& control);
TerminalTab(const winrt::TerminalApp::IPaneContent& content);
TerminalTab(std::shared_ptr<Pane> rootPane);
// Called after construction to perform the necessary setup, which relies on weak_ptr
@ -40,8 +40,7 @@ namespace winrt::TerminalApp::implementation
void SplitPane(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
winrt::Microsoft::Terminal::Control::TermControl& control);
const winrt::TerminalApp::IPaneContent& content);
void ToggleSplitOrientation();
winrt::fire_and_forget UpdateIcon(const winrt::hstring iconPath);

View file

@ -56,12 +56,17 @@
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.Terminal.Settings.Editor.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.CardExtension.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Provider.h>
#include <winrt/Windows.Storage.Pickers.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <winrt/Windows.Data.Json.h>
#include <winrt/AdaptiveCards.ObjectModel.Uwp.h>
#include <winrt/AdaptiveCards.Rendering.Uwp.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>

View file

@ -69,6 +69,7 @@ static constexpr std::string_view OpenSystemMenuKey{ "openSystemMenu" };
static constexpr std::string_view ClearBufferKey{ "clearBuffer" };
static constexpr std::string_view MultipleActionsKey{ "multipleActions" };
static constexpr std::string_view QuitKey{ "quit" };
static constexpr std::string_view HacktionKey{ "hacktion" };
static constexpr std::string_view ActionKey{ "action" };
@ -374,6 +375,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::ClearBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::MultipleActions, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::Quit, RS_(L"QuitCommandKey") },
{ ShortcutAction::Hacktion, L"Hacktion!" },
};
}();

View file

@ -82,7 +82,8 @@
ON_ALL_ACTIONS(OpenSystemMenu) \
ON_ALL_ACTIONS(ClearBuffer) \
ON_ALL_ACTIONS(MultipleActions) \
ON_ALL_ACTIONS(Quit)
ON_ALL_ACTIONS(Quit) \
ON_ALL_ACTIONS(Hacktion)
#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \