Compare commits

...

32 Commits

Author SHA1 Message Date
Michael Niksa
fa3c3abd29 Fix the fact that win32 builds don't put the objects in a folder... apparently. 2019-07-18 11:00:02 -07:00
Michael Niksa
181de80515 Add dependencies in SLN build order and runformat. 2019-07-17 16:00:08 -07:00
Michael Niksa
b83812349a Make WindowsTerminal project do it too. 2019-07-17 11:14:07 -07:00
Michael Niksa
0006a5b91b revert app changes so it will build correctly. 2019-07-17 11:03:55 -07:00
Michael Niksa
769f6aca8c try to make app use it 2019-07-16 16:33:54 -07:00
Michael Niksa
1c7aad82a9 try to move to shared pch 2019-07-16 15:43:13 -07:00
Mike Griese
0905140955 Refactor TerminalApp and Add Tests for Xaml Content (#1164)
* Refactors TerminalApp into two projects: 
  - TerminalAppLib, which builds a .lib, and includes all the code
  - TerminalApp, which builds a dll by linking the lib
* Adds a TerminalApp.Unit.Tests project
  - Includes the ability to test cppwinrt types we've authored using a SxS manifest for unpackaged winrt activation
  - includes the ability to test types with XAML content using an appxmanifest
* Adds a giant doc explaining how this was all done. Really, just go read that doc, it'll really help you understand what's going on in this PR.

-------------------------
These are some previous commit messages. They may be helpful to future readers.

* Start adding unittests for json parsing, end up creating a TerminalAppLib project to make a lib. See #1042

* VS automatically did this for me

* This is a dead end

  I tried including the idl-y things into the lib, but that way leads insanity

  If you want to make a StaticLibrary, then suddenly the winrt toolchain forgets
  that ProjectReferences can have winmd's in them, so it won't be able to
  compile any types from the referenced projects. If you instead try to manually
  reference the types, you'll get duplicate types up the wazoo, which of course
  is insane, since we're referencing them the _one_ time

* Yea just follow #1042 on github for status

  So current state:

  1. If you try to add a `Reference` to all of MUX.Markup, TerminalControl and
     TerminalSettings, then mdmerge will complain about all   the types from
     TerminalSettings being defined twice. In this magic scenario, the
     dependencies of TerminalControl are used directly   for some reason:

```
  12>    Load input metadata file ...OpenConsole\x64\Debug\TerminalSettings\Microsoft.Terminal.Settings.winmd.
  12>    Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.Settings.winmd.
  12>    Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.TerminalConnection.winmd.
  12>    Load input metadata file ...OpenConsole\x64\Debug\TerminalControl\Microsoft.Terminal.TerminalControl.winmd.
  12>    Load input metadata file ...OpenConsole\x64\Debug\Microsoft.UI.Xaml.Markup\Microsoft.UI.Xaml.Markup.winmd.
```

  2. If you don't add a `Reference` TerminalControl, then it'll complain about
     being unable to find the type TitleChangedEventArgs,   which is defined in
     TerminalControl.

  3. If you don't add a `Reference` TerminalSettings, then it'll complain about
     being unable to find the type KeyChord and other   types from
     TerminalSettings. In this scenario, it doesn't recurse on the other
     dependencies from TerminalControl for whatever   reason.

  4. If you instead try to add all 3 as a `ProjectReference`, then it'll
     complain about being unable to find TitleChangedEventArgs,   as in 2.
     Presumably, it;ll have troubles with the other types too, as none of the 3
     are actually included in the midlrt.rsp file.

  5. If you add all 3 as a `ProjectReference`, then also add TerminalControl as
     a `Reference`, you'll get a `MIDL2011: [msg]  unresolved type declaration
     Microsoft.UI.Xaml.Markup.XamlApplication`

  6. If you add all 3 as a `ProjectReference`, then also add TerminalControl AND
     MUX.Markup as a `Reference`, you'll get the same   result as 3.

* what if we just don't idl

  This seems to compile

* This compiles but I broke the MUX resources

  look at the App.xaml change. in this changelist. That's what's broken right now. Lets fix that!

* lets do this

    If I leave the MUX nuget out of the project, I'll get a compile error in
    App.xaml:

    ```
    ...OpenConsole\src\cascadia\TerminalApp\App.xaml(21,40): XamlCompiler error WMC0001: Unknown type 'XamlControlsResources' in XML namespace 'using:Microsoft.UI.Xaml.Controls'
    ```

    If I add it back to the project, it works

* Some cleanup from the previous commit

* This is busted again.

  Doing a clean build didn't work.

    A clean rebuild of the project, paired with some removal of dead code
    revealed a problem with what I have so far.

    TerminalAppLib depends on the generation of two headers,
    `AppKeyBindings.g.h` and `App.g.h`, as those define some of bits of the
    winrt types. They're needed to be able to compile the implementations.
    Presumably that's not getting generated by the lib project, because the dll
    project is the one to generate that file.

    So we need to move the idl's to the lib project. This created maddness,
    because of course the Duplicate Type thing. The solution to that is to
    actually mark the winrt DLLs that we're chaining up through us as

    ```
        <Private>false</Private>
        <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
    ```

    This will prevent them from getting double-included.

    This still doesn't work however, since
    ```
    app.cpp(40): error C2039: 'XamlMetaDataProvider': is not a member of 'winrt::TerminalApp'
    error C3861: 'XamlMetaDataProvider': identifier not found
    ```

    So we need to figure that out. The dll project is still generating the right
    header, so lets look there.

* Move the xaml stuff to the lib

  This compiles, but when we launch, we fail to load the tabviewcontrol
  resources again. So that's not what you want. Why is it not included?

* It works again!

  * Use the pri, xbf files from TerminalAppLib, not TerminalApp
  * Manually make TerminalApp include a reference to TerminalAppLib's
    TerminalApp.winmd. This will force the build to copy TerminalApp.winmd to
    TerminalApp/, which WindowsTerminal needs to be able to ProjectReference the
    TerminalApp project (it's expecting it to have a winmd)
  * Remove the module.g.cpp from TerminalApp, and move to TerminalAppLib. The
    dll doesn't do any codegen anymore.

* Agressively clean up these files

* Clean up unnecessary includes in the dll pch.h

* This does NOT work.

  The WindowsxamlManager call crashes. I'm thinking it has to do with activation
  of winrt types from a dll.

  Email out to @Austin-Lamb to see if he can assist

* This gets our cppwinrt types working, but xaml islands is still broken

* Split the tests apart, so they aren't insane

* These are the magic words to make xaml islands work

* All this witchcraft is necessary to make XAML+MUX work right

* Clean this up a bit and add comments

* Create an enormous doc explaining this madness

* Unsure how this got changed.

* Trying to get the CI build to work again.

  This resolves the MUX issue. We need to manually include it, because their package's target doesn't mark it as CopyLocalSatelliteAssemblies=false, Private=false.

  However, the TerminalApp project is still able to magically reason that the TerminalAppLib project should be included in the MdMerge step, because it think's it's a `GetCppWinRTStaticProjectReferences` reference.

* Update cppwinrt to the latest version - this fixes the MSBuild

  * I still need to re-add the KeyModifiers checks from TermControl. I think
    this update broke `operator&` for that enum.
  * There needs to be some cleanup obviously
  * The doc should be updated as well

* Clean up changes from cppwinrt update

* Try doing this, even though it seems wrong

* Lets try this (press x to doubt)

* Clean up vcxproj file, and remove appxmanifest change from previous commit

* Update to the latest TAEF release, maybe that'll work

* Let's try a prerelease version, shall we?

* Add notes about TAEF package, comment out tests

* Format the code

* Hopefully fix the arm64 and x86 builds

  also a typo

* Fix PR nits

* Fix some bad merge conflicts

* Some cleanup from the merge

* Well I was close to getting the merge right

* I believe this will fix CI

* Apply suggestions from code review

Co-Authored-By: Carlos Zamora <carlos.zamora@microsoft.com>

* These definitely need to be fixed

* Try version detecting in the test

  IDK if this will build, I'm letting the CI try while I clean rebuild locally

* Try blindly updating to the newest nuget version

* Revert "Try blindly updating to the newest nuget version"

This reverts commit b72bd9eb73.

* We're just going to see if these work in CI with this change

* Comment the tests back out. Windows Server 2019 is 10.0.17763.557

* Remove the nuget package

  We don't need this package anymore now that we're hosting it

* Okay this _was_ important
2019-07-15 14:27:56 -05:00
ksyx
fad7638bb3 user docs: Fix the capitalization on “Color Schemes” (#1953) 2019-07-13 11:17:11 -07:00
Michael Niksa
3377f06e52 Host our own NuGet feed for packages that we need that aren't elsewhere yet (#1951)
* Stop hosting packages inside of here. Put them on a blob storage account instead.
2019-07-12 15:22:03 -07:00
Dustin L. Howett (MSFT)
120e6157c3 Fix the WAP packaging project (#1900)
* Fix the WAP packaging project

This commits fixes the centennial package by:
* Forcing XBF (XAML binary format) files to be embedded in project
  PRI files.
* Moving package content generation to before PRI generation
* Collecting all of the package's PRI files to merge into resources.pri
* Fixing the hardcoded resource paths to reflect the new reality.

It also includes a magic value that fixes the bug where the project is
autodetected as a Mixed (CLR + Native) project.

Fixes #1816.
2019-07-12 15:21:45 -07:00
Dustin L. Howett (MSFT)
c1599248d7 Force the use of v2 (non-legacy) conhost when in ConPTY mode (#1935)
Fixes #1838.
2019-07-12 15:20:45 -07:00
Kayla Cinnamon
b706b60843 Style the button and tab view background to match the titlebar (#1934)
* styled title bar to be one color, shrunk + button
2019-07-12 15:07:03 -07:00
Mike Griese
f4e02d889c Don't NCPAINT our window, PAINT our window (#1898)
* This definitely works for getting shadow, pointy corners back

  Don't do anything in NCPAINT. If you do, you have to do everything. But the
  whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
  your normal paint. So just do that dummy.

  * This doesn't transition across monitors.
  * This has a window style change I think is wrong.
  * I'm not sure the margins change is important.

* The window style was _not_ important

* Still getting a black xaml islands area (the HRGN) when we switch to high DPI

* I don't know if this affects anything.

* heyo this works.

  I'm not entirely sure why. But if we only update the titlebar drag region when
  that actually changes, it's a _lot_ smoother. I'm not super happy with the
  duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
  I can't figure that out.

* Add more comments and cleanup

* Some PR nits, fix the titlebar painting on maximize
2019-07-12 14:46:27 -05:00
Force Charlie
02e8389518 Fix the conhost command line not being properly escaped (#1815)
This commit re-escapes the path to conhost's subprocess before it launches it.
2019-07-11 19:38:56 -07:00
Carlos Zamora
6d3001f3b8 Double and Triple Click Selection (#1197) 2019-07-11 16:06:18 -07:00
Dustin L. Howett (MSFT)
5b3a554da9 Update the README to clear out references to VS2017 (#1932) 2019-07-11 15:34:18 -07:00
Daniel Griffen
0219781753 Allow the DX rendering engine to run on Windows 7 (#1274)
Certain DirectX features are unavailable on windows 7. The important ones as they are used in the DX renderer are color font rendering and fallback font support. Color fonts did not exist at all on windows 7 so running basic glyphrun rendering should work just fine.

Fallback font support was not exposed to the user in windows 7, making dealing with them difficult. Rather than try to get some workarounds to properly enable it I have opted to just conditionally disable the support on windows 7.
2019-07-11 15:20:15 -07:00
Kayla Cinnamon
b9cc819afe Added links to user docs inside About popup (#1887)
* added links into about section

* added resources and aka.ms links

* moved links to resources

* Move the feedback URI into the resources too!
2019-07-11 21:01:46 +00:00
Michael Niksa
29522c472e Set utf-8 for the entire project (#1929)
* Set utf-8 for the entire project.
2019-07-11 13:13:10 -07:00
Brandon
7b8cf10fe0 Fix wrong maximized window offset on non primary monitors (#1921)
The overhang of a maximized window is currently calculated with this:
```cpp
auto offset = 0;
if (rcMaximum.left == 0)
{
    offset = windowPos->x;
}
else if (rcMaximum.top == 0)
{
    offset = windowPos->y;
}
```

This always works on the primary monitor but on a non primary monitor, it isn't always the case that `left` or `top` can be 0. Examples are when you offset a monitor. In those cases, `offset` will be 0 and the window will be cut off.

Instead I've changed the calculation to calculate the width of the windows frame which is how much it would overhang. Admittedly, the old calculation could be kept and take into consideration the current monitor.
2019-07-11 10:59:19 -07:00
Dustin L. Howett (MSFT)
60a444c630 Obstruct the user when they try to run WT under WOW (#1648)
* Obstruct the user when they try to run under WOW

* Move strings to resource file, add comments to methods, remove extraneous wil include.

* remove excess newline

* output of formatter.
2019-07-11 17:23:23 +00:00
James Holderness
594a7e4501 Fix interpretation of DECSTBM margin parameters (#1881)
* Fix DECSTBM parameter interpretation to ignore invalid ranges, and clear the margins on all full screen ranges.

* Add additional scroll margin adapter tests to verify the parameter configurations that were previously incorrect.

* Fix scroll margin adapter tests that weren't actually verifying the conditions that they claimed to be testing.
2019-07-10 15:41:16 -07:00
Summon528
3ce53adf56 Implement background image over acrylic or solid color (#1107) 2019-07-10 12:54:56 -07:00
Dustin L. Howett (MSFT)
3e5bb99478 inbox: reflect incoming changes up to uxp aa5182a2 (#1916) 2019-07-10 12:40:51 -07:00
Moshe Schorr
b970356600 Fixed DirectX RTL text issue where it'd be over other text / offscreen (#1873)
This is a partial fix of #538 . This does *not* change the Console RTL behavior, it does however fix an issue in the rendering. Basically, DirectX expects the origin to be on the right if it is going to draw RTL text. This PR is a simple fix for that. Rather than draw with the left point and then move the origin rightwards, we check if it's RTL, if so, we move the origin rightwards immediately, and then draw. LTR rendering is unchanged.
This doesn't fix underlying questions of RTL handling in the console. It's just a render bugfix. However, this render bugfix should still be a big help and solve the low-hanging issues.

## Validation Steps Performed
Behavior was tested. No changes were made to underlying console.
Three sample cases:
1. RTL text input
Before:
![image](https://user-images.githubusercontent.com/16987694/60816422-6737e100-a1a2-11e9-9e14-c62323fd5b02.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816395-5ab38880-a1a2-11e9-9f0a-17b03f8268ce.png)
2. Hebrew Output
Before (the Hebrew text is all being drawn to the left of the screen, hence the phantom text):
![image](https://user-images.githubusercontent.com/16987694/60816527-93ebf880-a1a2-11e9-9ba3-d3ebb46cc404.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816456-77e85700-a1a2-11e9-9783-9e69849f026d.png)
3. Mixed Output
So, this is where this is partial. Due to inherent stuff with RTL behavior, it doesn't look perfect. But the rendering itself is no longer at fault.
Before:
![image](https://user-images.githubusercontent.com/16987694/60816593-b5e57b00-a1a2-11e9-82be-0fcabb80f7d4.png)
After:
![image](https://user-images.githubusercontent.com/16987694/60816607-bb42c580-a1a2-11e9-849a-12846ec4d5c0.png)
2019-07-10 11:27:36 -07:00
James Holderness
0e6f290806 Fix margin boundary tests in the RI, DL, and IL escape sequences. (#1807)
* Fix margin boundary tests in the RI, DL, and IL sequences.
* Refactor the margin boundary tests into a reusable SCREEN_INFORMATION method.
* Add screen buffer unit tests for the RI, DL, and IL sequences.
2019-07-10 09:42:13 -07:00
Carlos Zamora
46d794b946 bugfix: crash on selection on wide glyphs in scrollback buffer (#1879) 2019-07-10 09:18:20 -07:00
Michael Ratanapintha
af1a4dd068 Added "Vintage" color scheme to defaults; fixes #1781 (#1901)
Testing done: All manual tests:
- Deleted profiles.json, started Terminal.
- Verified that the output "Vintage" color scheme existed.
- Verified that "Vintage" diffed equal to the "Classic" scheme
  in the issue, apart from the name and the addition of
  "background" and "foreground" colors, which I made equal
  to the "black" and "white" ones respectively.
- Verified that I could set a profile to use Vintage
  and that the colors changed accordingly.
2019-07-10 13:52:23 +00:00
Mike Griese
2de2f445c7 Enable resizing the panes with the keyboard. (#1207)
Adds the ability to resize panes with the keyboard. 

This is accomplished by making the Column/RowDefinitions for a Pane use `GridLengthHelper::FromPixels` to set their size. We store a pair of floats that represents the relative amount that each pane takes out of the parent pane. When the window is resized, we use that percentage to figure out the new size of each child in pixels, and manually size each column. 

Then, when the user presses the keybindings for resizePane{Left/Right/Up/Down}, we'll adjust those percentages, and resize the rows/cols as appropriate.

Currently, each pane adjusts the width/height by 5% of the total size at a time. I am not in love with this, but it works for now. I think when we get support for keybindings with arbitrary arg blobs, then we could do either a percent movement, or a number of characters at a time. The number of characters one would be trickier, because we'd have to get the focused control, and get the number of pixels per character, as adjacent panes might not have the same font sizes.
2019-07-10 08:27:12 -05:00
Dustin L. Howett (MSFT)
122f0de382 Move most of TerminalApp's runtime Xaml to a .xaml file and class (#1885) 2019-07-09 14:47:30 -07:00
Gautam Naik
cfbc9e8f9f Added fontSize and acrylicOpacity changing tip (#1889)
* Added fontSize and acrylicOpacity changing tip

Added Terminal tip about changing the font size and acrylic opacity using keyboard shortcuts.

* Update index.md
2019-07-09 12:19:06 -07:00
Michael Guntsche
bce8a79163 Make opening the settings file more robust (#1841)
* Make opening the settings file more robust

This fixes two issues.

 * Opens the assigned default application regardless of its configuration.
   Gvim for example only reacts to the "edit" verb so when selected as default application won't open.
   Using nullptr results in using the first specified application.
   This fixes #1789
 * If no application is assigned for json files fall back to notepad

 See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutea for more details
 especially why the result code checking is so horrific.

* Fix c-style cast
2019-07-09 07:29:44 -05:00
136 changed files with 4020 additions and 922 deletions

View File

@@ -5,7 +5,10 @@
<!-- Add repositories here to the list of available repositories -->
<!-- Dependencies that we must carry because they're not on public nuget feeds right now. -->
<add key="Static Package Dependencies" value="dep\packages" />
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
<!-- Use our own NuGet Feed -->
<add key="Windows Terminal NuGet Feed" value="https://terminalnuget.blob.core.windows.net/feed/index.json" />
<!-- Internal NuGet feeds that may not be accessible outside Microsoft corporate network -->
<!--<add key="TAEF - internal" value="https://microsoft.pkgs.visualstudio.com/DefaultCollection/_packaging/Taef/nuget/v3/index.json" />

View File

@@ -168,6 +168,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDx", "src\renderer\dx\lib\dx.vcxproj", "{48D21369-3D7B-4431-9967-24E81292CF62}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalConnection", "src\cascadia\TerminalConnection\TerminalConnection.vcxproj", "{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B} = {CA5CAD1A-E26F-4680-90EC-BE4F2617312B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalCore", "src\cascadia\TerminalCore\lib\TerminalCore-lib.vcxproj", "{CA5CAD1A-ABCD-429C-B551-8562EC954746}"
ProjectSection(ProjectDependencies) = postProject
@@ -177,6 +180,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalControl", "src\cascadia\TerminalControl\TerminalControl.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B} = {CA5CAD1A-E26F-4680-90EC-BE4F2617312B}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
{1CF55140-EF6A-4736-A403-957E4F7430BB} = {1CF55140-EF6A-4736-A403-957E4F7430BB}
@@ -184,6 +188,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalControl", "src\casc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B} = {CA5CAD1A-E26F-4680-90EC-BE4F2617312B}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
@@ -193,12 +198,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\casc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalSettings", "src\cascadia\TerminalSettings\TerminalSettings.vcxproj", "{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B} = {CA5CAD1A-E26F-4680-90EC-BE4F2617312B}
EndProjectSection
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "OpenConsolePackage", "pkg\appx\OpenConsolePackage.wapproj", "{2D310963-F3E0-4EE5-8AC6-FBC94DCC3310}"
EndProject
@@ -231,6 +240,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{89CDCC
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types.Unit.Tests", "src\types\ut_types\Types.Unit.Tests.vcxproj", "{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "src\cascadia\ut_app\TerminalApp.UnitTests.vcxproj", "{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedPch", "src\cascadia\SharedPch\SharedPch.vcxproj", "{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|ARM64 = AuditMode|ARM64
@@ -1102,6 +1124,60 @@ Global
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x64.Build.0 = Release|x64
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.ActiveCfg = Release|Win32
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.AuditMode|x86.Build.0 = AuditMode|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x64.Build.0 = Release|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.AuditMode|x86.Build.0 = Release|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-9A12-429C-B551-8562EC954746}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|x64.Build.0 = Release|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.AuditMode|x86.Build.0 = Release|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1160,6 +1236,9 @@ Global
{05500DEF-2294-41E3-AF9A-24E580B82836} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{1E4A062E-293B-4817-B20D-BF16B979E350} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-E26F-4680-90EC-BE4F2617312B} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View File

@@ -117,12 +117,12 @@ If you would like to ask a question that you feel doesn't warrant an issue (yet)
* You must be running Windows 1903 (build >= 10.0.18362.0) or above in order to run Windows Terminal.
* You must have the [1903 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) (build 10.0.18362.0) installed.
* You must have at least [VS 2017](https://visualstudio.microsoft.com/downloads/) installed.
* You must install the following Workloads via the VS Installer. If you're running VS 2019, opening the solution will [prompt you to install missing components automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/).
* You must have at least [VS 2019](https://visualstudio.microsoft.com/downloads/) installed.
* You must install the following Workloads via the VS Installer. Opening the solution will [prompt you to install missing components automatically](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/).
- Desktop Development with C++
- Universal Windows Platform Development
- Also install the following Individual Component:
- C++ (v141) Universal Windows Platform Tools
- **The following Individual Components**
- C++ (v142) Universal Windows Platform Tools
* You must also [enable Developer Mode in the Windows Settings app](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) to locally install and run the Terminal app.

View File

@@ -1,7 +0,0 @@
These packages are redistributed inside this folder because they are not yet available on a public NuGet feed.
## Microsoft.UI.XAML
This package is a custom development build fork to help us light up tab support. It will eventually go onto the same public feed as the existing `Microsoft.UI.XAML` package that's currently available on NuGet.org
## TAEF.Redist.WLK
This package is vetted for public redistribution and release, but the TAEF team hasn't set up a public feed to consume it yet. If/when they do, we'll move to that.

View File

@@ -12,6 +12,7 @@ Properties listed below affect the entire window, regardless of the profile sett
| `requestedTheme` | _Required_ | String | `system` | Sets the theme of the application. Possible values: `"light"`, `"dark"`, `"system"` |
| `showTerminalTitleInTitlebar` | _Required_ | Boolean | `true` | When set to `true`, titlebar displays the title of the selected tab. When set to `false`, titlebar displays "Windows Terminal". |
| `showTabsInTitlebar` | Optional | Boolean | `true` | When set to `true`, the tabs are moved into the titlebar and the titlebar disappears. When set to `false`, the titlebar sits above the tabs. |
| `wordDelimiters` | Optional | String | ` ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502` | Determines the delimiters used in a double click selection. |
## Profiles
Properties listed below are specific to each unique profile.

View File

@@ -0,0 +1,527 @@
# Getting TAEF unittests to work with a C++/WinRT XAML Islands application
* __Author__: Mike Griese @zadjii-msft
* __Created on__: 2019-06-06
So you've built a Win32 application that uses XAML Islands to display it's UI
with C++/WinRT. How do you go about adding unittests to this application? I'm
going to cover the steps that I took to get the Windows Terminal updated to be
able to test not only our C++/WinRT components, but also pure c++ classes that
were used in the application, and components that used XAML UI elements.
## Prerequisites
Make sure you're using at least the 2.0.190605.7 version of the CppWinRT nuget
package. Prior to this version, there are some bugs with C++/WinRT's detection
of static lib dependencies. You might be able to get your build working with
Visual Studio on earlier versions, but not straight from MsBuild.
Also, if you're going to be running your tests in a CI build of some sort, make
sure that your tests are running on a machine running at least Windows 18362. If
your CI isn't running that version, then this doesn't matter at all.
Furthermore, you may need an updated TAEF package as well. Our CI uses the TAEF
VsTest adapter to allow ADO to run TAEF tests in CI. However, there's a bug in
the tests adapter that prevents it from running tests in a UAP context. The
`10.38.190605002` TAEF is the most recent release at the time of writing,
however, that doesn't have the fix necessary. Fortunately, the TAEF team was
kind enough to prototype a fix for us, which is the version
`10.38.190610001-uapadmin`, which we're using in this repo until an official
release with the fix is available.
## Move the C++/WinRT implementation to a static lib
By default, most (newly authored) C++/WinRT components are authored as a dll
that can be used to activate your types. However, you might have other classes
in that binary that you want to be able to test, which aren't winrt types. If
the implementation is sitting in a DLL, it'll be hard to write a TAEF unittest
dll that can call the pure c++ types you've defined.
The first thing you're going to need to do is move the implementation of your
winrt component from a dll to a static lib. Once you have the static lib, we'll
be able to link it into the dll you were previously producing, as well as being
able to link it into the dll we'll be using to test the types. Once this is
complete, your dll project will exist as little more than some extra packaging
for your new lib, as all your code will be built by the lib.
To aid in this description, I'll be referring to the projects that we changed.
The dll project we changed to a lib was the `TerminalApp` project. From it, we
created a new `TerminalAppLib` project, and changed `TerminalApp` to create a
dll by linking the lib `TerminalAppLib` produced.
### Create the static lib project
We'll start by creating a new static lib project. The easiest way to do this is
by copying your existing dll `vcxproj` file into a new file. Make sure to change
the `ProjectGuid` and to add the new project to your `.sln` file. Then, change
the `ConfigurationType` to `StaticLibrary`. This Lib should be responsible for
building all of your headers, `.cpp` files, `.idl`s for your winrt types, and
any `.xaml` files you might have.
You'll likely need to place this new file into a separate directory from the
existing dll project, as C++/WinRT uses the project directory as the root of the
intermediate build tree. Each directory should only have one `.vcxproj` file in
it. For the Terminal project, we created a subdirectory `lib/` underneath
`TerminalApp/`, and updated the `Include` paths to properly point at the
original files. You could alternatively put all the source in one directory, and
have separate `dll/` and `lib/` subdirectories from the source that are solely
responsible for building their binary.
At this point, you might face some difficulty including the right wimnd
references, especially from other C++/WinRT dependencies for this project that
exist in your solution. I don't know why, but I had a fair amount of difficulty
using a `ProjectReference` from a C++/WinRT StaticLibrary to another C++/WinRT
project in my solution. If you're referring to any other projects, you'll need
to set up a reference to their built `.winmd`'s manually.
As an example, here's how we've added a reference to the `TerminalSettings`
project from our `TerminalAppLib` project:
```xml
<ItemGroup>
<!-- Manually add references to each of our dependent winmds. Mark them as
private=false and CopyLocalSatelliteAssemblies=false, so that we don't
propogate them upwards (which can make referencing this project result in
duplicate type definitions)-->
<Reference Include="Microsoft.Terminal.Settings">
<HintPath>$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\Microsoft.Terminal.Settings.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
</ItemGroup>
```
The `HintPath` may be different depending on your project structure - verify
locally the right path to the `.winmd` file you're looking for.
Notably, you'll also need to put a `pch.h` and `pch.cpp` in the new lib's
directory, and use them instead of the `pch.h` used by the dll. C++/WinRT will be
very angry with you if you try to use a `pch.h` in another directory. Since
we're putting all the code into the static lib project, take your existing
`pch.h` and move it to the lib project's directory and create an empty `pch.h`
in the dll project's directory.
### Update the dll project
Now that we havea lib that builds all your code, we can go ahead and tear out
most of the dead code from the old dll project. Remove all the source files from
the dll's `.vcxproj` file, save for the `pch.h` and `pch.cpp` files. You _may_
need to leave the headers for any C++/WinRT types you've authored in this project
- I'm not totally sure it's necessary.
Now, to link the static lib we've created. For whatever reason, adding a
`ProjectReference` to the static lib doesn't work. So, we'll need to manually
link the lib from the lib project. You can do that by adding the lib's output
dir to your `AdditionalLibraryDirectories`, and adding the lib to your
`AdditionalDependencies`, like so:
```xml
<ItemDefinitionGroup>
<Link>
<!-- Manually link with the TerminalAppLib.lib we've built. -->
<AdditionalLibraryDirectories>$(SolutionDir)\$(Platform)\$(Configuration)\TerminalAppLib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>TerminalAppLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
```
We are NOT adding a reference to the static lib project's .winmd here. As of the
2.0.190605.7 CppWinRT nuget package, this is enough for MsBuild and Visual
Studio to be able to determine that the static lib's `.winmd` should be included
in this package.
At this point, you might have some mdmerge errors, which complain about
duplicate types in one of your dependencies. This might especially happen if one
of your dependencies (ex `A.dll`) is also a dependency for one of your _other_
dependencies (ex `B.dll`). In this example, your final output project `C.dll`
depends on both `A.dll` and `B.dll`, and `B.dll` _also_ depends on `A.dll`. If
you're seeing this, I recommend adding `Private=false` and
`CopyLocalSatelliteAssemblies=false` to your dependent dlls. In this example,
add similar code to `B.dll`:
```xml
<ProjectReference Include="$(SolutionDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj">
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
```
where `TerminalSettings` is your `A.dll`, which is included by both `B` and `C`.
We additionally had an `.exe` project that was including our `TerminalApp`
project, and all its `.xbf` and `.pri` files. If you have a similar project
aggregating all your resources, you might need to update the paths to point to
the new static lib project.
At this point, you should be able to rebuild your solution, and everything
should be working just the same as before.
## Add TAEF Tests
Now that you have a static library project, you can start building your unittest
dll. Start by creating a new directory for your unittest code, and creating a
`.vcxproj` for a TAEF unittest dll. For the Terminal solution, we use the TAEF
nuget package `Taef.Redist.Wlk`.
### Referencing your C++/WinRT static lib
This step is the easiest. Add a `ProjectReference` to your static lib project,
and your lib will be linked into your unittest dll.
```xml
<ProjectReference Include="$(SolutionDir)\src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" />
```
Congratulations, you can now instantiate the pure c++ types you've authored in
your static lib. But what if you want to test your C++/WinRT types too?
### Using your C++/WinRT types
To be able to instantiate your C++/WinRT types in a TAEF unittest, you'll need
to rely on a new feature to Windows in version 1903 which enables unpackaged
activation of WinRT types. To do this, we'll need to author a SxS manifest that
lists each of our types, and include it in the dll, and also activate it
manually from TAEF.
#### Creating the manifest
First, you need to create a manifest file that lists each dll your test depends
upon, and each of the types in that dll. For example, here's an excerpt from the
Terminal's manifest:
```xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="TerminalSettings.dll" hashalg="SHA1">
<activatableClass name="Microsoft.Terminal.Settings.KeyChord" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.Terminal.Settings.TerminalSettings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="TerminalApp.dll" hashalg="SHA1">
<activatableClass name="TerminalApp.App" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="TerminalApp.AppKeyBindings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="TerminalApp.XamlmetaDataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
</assembly>
```
Here we have two dlls that we depend upon, `TerminalSettings.dll` and
`TerminalApp.dll`. `TerminalSettings` implements two types,
`Microsoft.Terminal.Settings.KeyChord` and
`Microsoft.Terminal.Settings.TerminalSettings`.
#### Linking the manifest to the test dll
Now that we have a manifest file, we need to embed it in your unittest dll. This
is done with the following properties in your `vcxproj` file:
```xml
<PropertyGroup>
<GenerateManifest>true</GenerateManifest>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<ItemGroup>
<Manifest Include="TerminalApp.Unit.Tests.manifest" />
</ItemGroup>
```
where `TerminalApp.Unit.Tests.manifest` is the name of your manifest file.
Additionally, you'll need to binplace the manifest _adjacent to your test
binary_, so TAEF can find it at runtime. I've done this in the following way,
though I'm sure there's a better way:
```xml
<ItemDefinitionGroup>
<PostBuildEvent>
<!-- Manually copy the manifest to our outdir, because the test will need
to find it adjacent to us. -->
<Command>
(xcopy /Y &quot;$(OpenConsoleDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.manifest*&quot; )
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
```
#### Copying your dependencies
Additionally, any dlls that implement any types your test is dependent upon will
also need to be in the output directory for the test. Manually copy those DLLs
to the tests' output directory too. The updated `PostBuildEvent` looks like
this:
```xml
<ItemDefinitionGroup>
<PostBuildEvent>
<Command>
echo OutDir=$(OutDir)
(xcopy /Y &quot;$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.manifest*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalConnection\TerminalConnection.dll&quot; &quot;$(OutDir)\TerminalConnection.dll*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\TerminalSettings.dll&quot; &quot;$(OutDir)\TerminalSettings.dll*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalControl\TerminalControl.dll&quot; &quot;$(OutDir)\TerminalControl.dll*&quot; )
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
```
Again, verify the correct paths to your dependant C++/WinRT dlls, as they may be
different than the above
#### Activating the manifest from TAEF
Now that the manifest lives adjacent to your test dll, and all your dependent
dlls are also adjacent to the unittest dll, there's only one thing left to do.
TAEF will not use your dll's manifest by default, so you'll need to add a
property to your test class/method to tell TAEF to do so. You can do this with
the following:
```c++
class SettingsTests
{
// Use a custom manifest to ensure that we can activate winrt types from
// our test. This property will tell taef to manually use this as the
// sxs manifest during this test class. It includes all the C++/WinRT
// types we've defined, so if your test is crashing for an unknown
// reason, make sure it's included in that file.
BEGIN_TEST_CLASS(SettingsTests)
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
END_TEST_CLASS()
// Other Test code here
}
```
Now, if you try to add any test methods that instantiate WinRT types you've
authored, they'll work. That is of course, so long as they don't use XAML. If
you want to use any XAML types, then you'll have to keep reading.
### Using Xaml Types (with XAML Islands)
To be able to instatiate XAML types in your unittest, we'll need to make use of
the [XAML Hosting
API](https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/using-the-xaml-hosting-api)
(Xaml Islands). This enables you to use XAML APIs from a Win32 context.
#### Adding XAML Hosting code
First and foremost, you'll need to add the following to your test's `precomp.h`:
```c++
#include <winrt/Windows.system.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
```
If you hit a compile warning that refers to `GetCurrentTime`, you'll probably
also need the following, after you've `#include`'d `Windows.h`:
```c++
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
```
Then, somewhere in your test code, you'll need to start up Xaml Islands. I've done this in my `TEST_CLASS_SETUP`, so that I only create it once, and re-use it for each method.
```c++
class TabTests
{
TEST_CLASS_SETUP(ClassSetup)
{
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Initialize the Xaml Hosting Manager
_manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
_source = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
return true;
}
private:
winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager _manager{ nullptr };
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source{ nullptr };
```
#### Authoring your test's `AppxManifest.xml`
This alone however is not enough to get XAML Islands to work. There was a fairly
substantial change to the XAML Hosting API around Windows build 18295, so it
explicitly requires that you have your executable's manifest set
`maxversiontested` to higher than that version. However, because TAEF's `te.exe`
is not so manifested, we can't just use our SxS manifest from before to set that
version. Instead, you'll need to make TAEF run your test binary in a packaged
content, with our own appxmanifest.
To do this, we'll need to author an `Appxmanifest.xml` to use with the test, and
associate that manifest with the test.
Here's the AppxManifest we're using:
```xml
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap">
<Identity Name="TerminalApp.Unit.Tests.Package"
ProcessorArchitecture="neutral"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="1.0.0.0"
ResourceId="en-us" />
<Properties>
<DisplayName>TerminalApp.Unit.Tests.Package Host Process</DisplayName>
<PublisherDisplayName>Microsoft Corp.</PublisherDisplayName>
<Logo>taef.png</Logo>
<Description>TAEF Packaged Cwa FullTrust Application Host Process</Description>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
<Resources>
<Resource Language="en-us" />
</Resources>
<Applications>
<Application Id="TE.ProcessHost" Executable="TE.ProcessHost.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="TAEF Packaged Cwa FullTrust Application Host Process" Square150x150Logo="taef.png" Square44x44Logo="taef.png" Description="TAEF Packaged Cwa Application Host Process" BackgroundColor="#222222">
<uap:SplashScreen Image="taef.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TerminalSettings.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.TerminalSettings" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.KeyChord" ThreadingModel="both" />
</InProcessServer>
</Extension>
<!-- More extensions here -->
</Extensions>
</Package>
```
Change the `Identity.Name` and `Properties.DisplayName` to be more appropriate
for your test, as well as other properties if you feel the need. TAEF will
deploy the test package and remove it from your machine during testing, so it
doesn't terribly matter what these values are.
MAKE SURE that `MaxVersionTested` is higher than `10.0.18295.0`. If it isn't,
XAML islands will still prevent you from activating it.
UNDER NO CIRCUMSTANCE should you change the `<Application Id="TE.ProcessHost"
Executable="TE.ProcessHost.exe" EntryPoint="Windows.FullTrustApplication">`
line. This is how TAEF activates the TAEF host for your test binary. You might
get a warning about `TE.ProcessHost.exe` being deprecated in favor of
`TE.ProcessHost.UAP.exe`, but I haven't had success with the UAP version.
Lower in the file, you'll see the `Extensions` block. In here you'll put each of
the winrt dependencies that your test needs, much like we did for the previous
manifest. Note that the syntax is _not_ exactly the same as the SxS manifest.
#### Copy the AppxManifest to your `$(OutDir)`
Again, we'll need to copy this appxmanifest adjacent to the test binary so we
can load it from the test. We'll do this similar to how we did the SxS manifest
before. The complete `PostBuildEvent` now looks like this:
```xml
<ItemDefinitionGroup>
<PostBuildEvent>
<Command>
(xcopy /Y &quot;$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.manifest*&quot; )
(xcopy /Y &quot;$(SolutionDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.AppxManifest.xml&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.AppxManifest.xml*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalConnection\TerminalConnection.dll&quot; &quot;$(OutDir)\TerminalConnection.dll*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalSettings\TerminalSettings.dll&quot; &quot;$(OutDir)\TerminalSettings.dll*&quot; )
(xcopy /Y &quot;$(SolutionDir)$(Platform)\$(Configuration)\TerminalControl\TerminalControl.dll&quot; &quot;$(OutDir)\TerminalControl.dll*&quot; )
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
```
The new line here is the line referencing
`TerminalApp.Unit.Tests.AppxManifest.xml`. You can only have one
`PostBuildEvent` per project, so don't go re-defining it for each additional
step - MsBuild will only use the last one. Again, this is probably not the best
way of copying these files over, but it works.
#### Use the AppxManifest in the test code
Now that we have the AppxManifest being binplaced next to our test, we can
finally reference it in the test. Instead of using the `ActivationContext` from
before, we'll use two new properties to tell TAEF to run this test as a package,
and to use our manifest as the AppxManifest for the package.
```c++
BEGIN_TEST_CLASS(TabTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TerminalApp.Unit.Tests.AppxManifest.xml")
END_TEST_CLASS()
```
The complete Xaml Hosting test now looks like this:
```c++
class TabTests
{
BEGIN_TEST_CLASS(TabTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TerminalApp.Unit.Tests.AppxManifest.xml")
END_TEST_CLASS()
TEST_METHOD(TryCreateXamlObjects);
TEST_CLASS_SETUP(ClassSetup)
{
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Initialize the Xaml Hosting Manager
_manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
_source = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
return true;
}
private:
winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager _manager{ nullptr };
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source{ nullptr };
};
void TabTests::TryCreateXamlObjects(){ ... }
```
Congratulations, you can now use XAML types from your unittest.
### Using types from `Microsoft.UI.Xaml`
Let's say you're extra crazy and you're using the `Microsoft.UI.Xaml` nuget
package. If you've followed all the steps above exactly, you're probably already
fine! You've already put the types in your appxmanifest (there are a lot of
them). You should be able to call the `Microsoft.UI.Xaml` types without any
problems.
This is because of a few key lines we already put in the appxmanifest:
```xml
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
```
Without these `PackageDependency` entries for the VCLibs, Microsoft.UI.Xaml.dll
will not be able to load.

View File

@@ -75,7 +75,7 @@ The profile GUID is used to reference the default profile in the global settings
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch)
## color Schemes
## Color Schemes
Each scheme defines the color values to be used for various terminal escape sequences.
Each schema is identified by the name field. Examples include

View File

@@ -85,4 +85,6 @@ The list of valid settings can be found in the [Profiles.json Documentation](../
(ref https://twitter.com/r_keith_hill/status/1142871145852440576)
2. Please add more Tips and Tricks
2. Terminal zoom can be changed by holding `Ctrl` and scrolling with mouse.
3. If `useAcrylic` is enabled in profiles.json, background opacity can be changed by holding `Ctrl+Shift` and scrolling with mouse.
4. Please add more Tips and Tricks

BIN
msbuild.binlog Normal file

Binary file not shown.

BIN
msbuild2.binlog Normal file

Binary file not shown.

View File

@@ -22,6 +22,7 @@
<PropertyGroup>
<ProjectGuid>CA5CAD1A-224A-4171-B13A-F16E576FDD12</ProjectGuid>
<EntryPointProjectUniqueName>..\WindowsTerminal\WindowsTerminal.vcxproj</EntryPointProjectUniqueName>
<DebuggerType>NativeOnly</DebuggerType>
</PropertyGroup>
<PropertyGroup Condition="!Exists('CascadiaPackage_TemporaryKey.pfx')">
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
@@ -260,12 +261,11 @@
</ItemGroup>
<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />
<!--
This exists to work around Microsoft/microsoft-ui-xaml#494.
https://github.com/Microsoft/microsoft-ui-xaml/issues/494
Microsoft.UI.Xaml contains some <Content> resource files that need to be included in our package.
For some reason, they're not rolled up through dependent projects; if they were, their paths would
be wrong.
Because the MUX nuget package hardcodes a requirement that the consuming project
be of type 'UAP', its resources are included in packaging and dependency resolution
by default. Inject them here.
WAP Packaging projects don't actually support nuget package references, so we added one manually.
This does mean that version changes to Microsoft.UI.Xaml must be manually reflected
here.
@@ -277,17 +277,6 @@
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<PropertyGroup>
<WapProjBeforeGenerateAppxManifestDependsOn>
$(WapProjBeforeGenerateAppxManifestDependsOn);
_ConsoleInjectMUXWinmdIntoReferences;
</WapProjBeforeGenerateAppxManifestDependsOn>
</PropertyGroup>
<Target Name="_ConsoleInjectMUXWinmdIntoReferences">
<ItemGroup>
<_WinmdFilesFromReferences Include="@(Reference)" Condition="'%(Reference.Filename)' == 'Microsoft.UI.Xaml' and '%(Reference.Extension)' == '.winmd'" />
</ItemGroup>
</Target>
<!-- End workaround -->
<ItemGroup>
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
@@ -310,4 +299,25 @@
</_FilteredNonWapProjProjectOutput>
</ItemGroup>
</Target>
<!-- Move all the PRI files that would be packaged into the appx into _PriFile so that
GenerateProjectPriFile catches them. This requires us to move payload collection
up before GenerateProjectPriFile, when it is typically _after_ it (because the
DesktopBridge project type is built to only prepare the payload during appx manifest
generation.
Since PRI file generation is _before_ manifest generation (for possibly obvious or
important reasons), that doesn't work for us.
-->
<PropertyGroup>
<_GenerateProjectPriFileDependsOn>OpenConsoleLiftDesktopBridgePriFiles;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
</PropertyGroup>
<Target Name="OpenConsoleLiftDesktopBridgePriFiles" DependsOnTargets="_ConvertItems">
<ItemGroup>
<_PriFile Include="@(_NonWapProjProjectOutput)" Condition="'%(Extension)' == '.pri'" />
<!-- Remove all other .pri files from the appx payload. -->
<AppxPackagePayload Remove="@(AppxPackagePayload)" Condition="'%(Extension)' == '.pri'" />
</ItemGroup>
</Target>
</Project>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@@ -156,4 +156,28 @@
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal (Dev)</value>
</data>
</root>
<data name="DocumentationLabelText" xml:space="preserve">
<value>Documentation
</value>
</data>
<data name="GettingStartedLabelText" xml:space="preserve">
<value>Getting Started
</value>
</data>
<data name="ReleaseNotesLabelText" xml:space="preserve">
<value>Release Notes
</value>
</data>
<data name="DocumentationUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-documentation</value>
</data>
<data name="GettingStartedUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-getting-started</value>
</data>
<data name="ReleaseNotesUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-release-notes</value>
</data>
<data name="FeedbackUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-feedback</value>
</data>
</root>

View File

@@ -0,0 +1,54 @@
<?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">
<SharedPchDir Condition="$(Platform) != 'Win32'">$(SolutionDir)src\cascadia\SharedPch\$(Platform)\$(Configuration)\</SharedPchDir>
<SharedPchDir Condition="$(Platform) == 'Win32'">$(SolutionDir)src\cascadia\SharedPch\$(Configuration)\</SharedPchDir>
<SharedPch>$(SharedPchDir)pch.pch</SharedPch>
<SharedPchObj>$(SharedPchDir)pch.obj</SharedPchObj>
<SharedPdb>$(SharedPchDir)SharedPch.pdb</SharedPdb>
<SharedIdb>$(SharedPchDir)SharedPch.idb</SharedIdb>
<SharedDest Condition="'$(ConfigurationType)' != 'StaticLibrary'">$(IntDir)vc$(PlatformToolsetVersion)</SharedDest>
<SharedDest Condition="'$(ConfigurationType)' == 'StaticLibrary'">$(IntDir)$(ProjectName)</SharedDest>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)\src\cascadia\SharedPch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderOutputFile>$(SharedPch)</PrecompiledHeaderOutputFile>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="SharedPchDir">
<Value>$(SharedPchDir)</Value>
</BuildMacro>
<BuildMacro Include="SharedPch">
<Value>$(SharedPch)</Value>
</BuildMacro>
<BuildMacro Include="SharedPdb">
<Value>$(SharedPdb)</Value>
</BuildMacro>
<BuildMacro Include="SharedIdb">
<Value>$(SharedIdb)</Value>
</BuildMacro>
<Link Include="$(SharedPchObj)"/>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\SharedPch\SharedPch.vcxproj">
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Target Name="RemoveStaticWinmdReferenceForSharedPch" BeforeTargets="GetCppWinRTStaticWinMDReferences">
<ItemGroup>
<CppWinRTStaticProjectReferences Remove="@(CppWinRTStaticProjectReferences)"
Condition="'%(ReferenceOutputAssembly)' != 'true'" />
</ItemGroup>
</Target>
<Target Name="CopySharedPDBs" BeforeTargets="ClCompile">
<Copy SourceFiles="$(SharedPdb)"
DestinationFiles="$(SharedDest).pdb"
Condition="Exists($(SharedPdb))" />
<Copy SourceFiles="$(SharedIdb)"
DestinationFiles="$(SharedDest).idb"
Condition="Exists($(SharedIdb))" />
</Target>
</Project>

View File

@@ -0,0 +1,59 @@
<?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.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup>
<!-- cppwinrt.build.pre.props depends on these settings: -->
<!-- build a dll, not exe (Application) -->
<ConfigurationType>StaticLibrary</ConfigurationType>
<SubSystem>Console</SubSystem>
<!-- sets a bunch of Windows Universal properties -->
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{CA5CAD1A-E26F-4680-90EC-BE4F2617312B}</ProjectGuid>
<ProjectName>SharedPch</ProjectName>
<RootNamespace>Microsoft.Terminal.SharedPch</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<!--
DON'T REDIRECT OUR OUTPUT.
Setting this will tell cppwinrt.build.post.props to copy our output from
the default OutDir up one level, so the wapproj will be able to find it.
-->
<NoOutputRedirection>true</NoOutputRedirection>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<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.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
</packages>

View File

@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#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 NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <shellscalingapi.h>
#include <LibraryIncludes.h>
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <unknwn.h>
#include <hstring.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Documents.h"
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <winrt/Windows.System.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
#include <telemetry\ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
// JsonCpp
#include <json.h>
#include <shellapi.h>
#include <filesystem>

View File

@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#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 NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <shellscalingapi.h>
#include <LibraryIncludes.h>
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <unknwn.h>
#include <hstring.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Documents.h"
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <winrt/Windows.System.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
#include <telemetry\ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
// JsonCpp
#include <json.h>
#include <shellapi.h>
#include <filesystem>

View File

@@ -6,6 +6,7 @@
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
#include "App.g.cpp"
#include "TerminalPage.h"
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::UI::Xaml;
@@ -76,110 +77,45 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Create all of the initial UI elements of the Terminal app.
// * Creates the tab bar, initially hidden.
// * Creates the tab content area, which is where we'll display the tabs/panes.
// * Initializes the first terminal control, using the default profile,
// and adds it to our list of tabs.
void App::_Create(uint64_t parentHwnd)
{
_tabView = MUX::Controls::TabView{};
/* !!! TODO
This is not the correct way to host a XAML page. This exists today because we valued
getting a .xaml over tearing out all of the terminal logic and splitting it across App
and Page.
The work to clarify the boundary between app global state and "terminal page" state
is tracked in GH#1878.
*/
auto terminalPage = winrt::make_self<TerminalPage>();
_root = terminalPage.as<winrt::Windows::UI::Xaml::Controls::Control>();
_tabContent = terminalPage->TabContent();
_tabRow = terminalPage->TabRow();
_tabView = terminalPage->TabView();
_newTabButton = terminalPage->NewTabButton();
_tabView.SelectionChanged({ this, &App::_OnTabSelectionChanged });
_tabView.TabClosing({ this, &App::_OnTabClosing });
_tabView.Items().VectorChanged({ this, &App::_OnTabItemsChanged });
_minMaxCloseControl = terminalPage->MinMaxCloseControl();
_minMaxCloseControl.ParentWindowHandle(parentHwnd);
_root = Controls::Grid{};
if (!_settings->GlobalSettings().GetShowTabsInTitlebar())
{
_minMaxCloseControl.Visibility(Visibility::Collapsed);
}
_tabRow = Controls::Grid{};
_tabRow.Name(L"Tab Row");
_tabContent = Controls::Grid{};
_tabContent.Name(L"Tab Content");
// Set up two columns in the tabs row - one for the tabs themselves, and
// another for the settings button.
auto tabsColDef = Controls::ColumnDefinition();
auto newTabBtnColDef = Controls::ColumnDefinition();
newTabBtnColDef.Width(GridLengthHelper::Auto());
_tabRow.ColumnDefinitions().Append(tabsColDef);
_tabRow.ColumnDefinitions().Append(newTabBtnColDef);
// Set up two rows - one for the tabs, the other for the tab content,
// the terminal panes.
auto tabBarRowDef = Controls::RowDefinition();
tabBarRowDef.Height(GridLengthHelper::Auto());
_root.RowDefinitions().Append(tabBarRowDef);
_root.RowDefinitions().Append(Controls::RowDefinition{});
_root.Children().Append(_tabRow);
Controls::Grid::SetRow(_tabRow, 0);
_root.Children().Append(_tabContent);
Controls::Grid::SetRow(_tabContent, 1);
Controls::Grid::SetColumn(_tabView, 0);
// Create the new tab button.
_newTabButton = Controls::SplitButton{};
Controls::SymbolIcon newTabIco{};
newTabIco.Symbol(Controls::Symbol::Add);
_newTabButton.Content(newTabIco);
Controls::Grid::SetRow(_newTabButton, 0);
Controls::Grid::SetColumn(_newTabButton, 1);
_newTabButton.VerticalAlignment(VerticalAlignment::Stretch);
_newTabButton.HorizontalAlignment(HorizontalAlignment::Left);
// When the new tab button is clicked, open the default profile
// Event Bindings (Early)
_newTabButton.Click([this](auto&&, auto&&) {
this->_OpenNewTab(std::nullopt);
});
_tabView.SelectionChanged({ this, &App::_OnTabSelectionChanged });
_tabView.TabClosing({ this, &App::_OnTabClosing });
_tabView.Items().VectorChanged({ this, &App::_OnTabItemsChanged });
_root.Loaded({ this, &App::_OnLoaded });
// Populate the new tab button's flyout with entries for each profile
_CreateNewTabFlyout();
_tabRow.Children().Append(_tabView);
if (_settings->GlobalSettings().GetShowTabsInTitlebar())
{
_minMaxCloseControl = winrt::TerminalApp::MinMaxCloseControl(parentHwnd);
Controls::Grid::SetRow(_minMaxCloseControl, 0);
Controls::Grid::SetColumn(_minMaxCloseControl, 1);
_minMaxCloseControl.Content().Children().Append(_newTabButton);
_tabRow.Children().Append(_minMaxCloseControl);
}
else
{
_tabRow.Children().Append(_newTabButton);
}
_tabContent.VerticalAlignment(VerticalAlignment::Stretch);
_tabContent.HorizontalAlignment(HorizontalAlignment::Stretch);
// Here, we're doing the equivalent of defining the _tabRow as the
// following: <Grid Background="{ThemeResource
// ApplicationPageBackgroundThemeBrush}"> We need to set the Background
// to that ThemeResource, so it'll be colored appropriately regardless
// of what theme the user has selected.
// We're looking up the Style we've defined in App.xaml, and applying it
// here. A ResourceDictionary is a Map<IInspectable, IInspectable>, so
// you'll need to try_as to get the type we actually want.
auto res = Resources();
IInspectable key = winrt::box_value(L"BackgroundGridThemeStyle");
if (res.HasKey(key))
{
IInspectable g = res.Lookup(key);
winrt::Windows::UI::Xaml::Style style = g.try_as<winrt::Windows::UI::Xaml::Style>();
_root.Style(style);
_tabRow.Style(style);
}
// Apply the UI theme from our settings to our UI elements
_ApplyTheme(_settings->GlobalSettings().GetRequestedTheme());
_OpenNewTab(std::nullopt);
_root.Loaded({ this, &App::_OnLoaded });
_tabContent.SizeChanged({ this, &App::_OnContentSizeChanged });
}
// Method Description:
@@ -210,9 +146,10 @@ namespace winrt::TerminalApp::implementation
dialog.Content(contentElement);
dialog.CloseButtonText(closeButtonText);
// IMPORTANT: Add the dialog to the _root UIElement before you show it,
// so it knows how to attach to the XAML content.
_root.Children().Append(dialog);
// IMPORTANT: This is necessary as documented in the ContentDialog MSDN docs.
// Since we're hosting the dialog in a Xaml island, we need to connect it to the
// xaml tree somehow.
dialog.XamlRoot(_root.XamlRoot());
// Display the dialog.
Controls::ContentDialogResult result = co_await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup);
@@ -242,32 +179,74 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Show a dialog with "About" information. Displays the app's Display
// Name, and the version.
// Name, version, getting started link, documentation link, and release
// Notes link.
void App::_ShowAboutDialog()
{
auto resourceLoader = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView();
const auto title = resourceLoader.GetString(L"AboutTitleText");
const auto versionLabel = resourceLoader.GetString(L"VersionLabelText");
const auto gettingStartedLabel = resourceLoader.GetString(L"GettingStartedLabelText");
const auto documentationLabel = resourceLoader.GetString(L"DocumentationLabelText");
const auto releaseNotesLabel = resourceLoader.GetString(L"ReleaseNotesLabelText");
const auto gettingStartedUriValue = resourceLoader.GetString(L"GettingStartedUriValue");
const auto documentationUriValue = resourceLoader.GetString(L"DocumentationUriValue");
const auto releaseNotesUriValue = resourceLoader.GetString(L"ReleaseNotesUriValue");
const auto package = winrt::Windows::ApplicationModel::Package::Current();
const auto packageName = package.DisplayName();
const auto version = package.Id().Version();
Windows::UI::Xaml::Media::SolidColorBrush blueBrush{ Windows::UI::ColorHelper::FromArgb(255, 0, 115, 207) };
winrt::Windows::UI::Xaml::Documents::Run about;
winrt::Windows::UI::Xaml::Documents::Run gettingStarted;
winrt::Windows::UI::Xaml::Documents::Run documentation;
winrt::Windows::UI::Xaml::Documents::Run releaseNotes;
winrt::Windows::UI::Xaml::Documents::Hyperlink gettingStartedLink;
winrt::Windows::UI::Xaml::Documents::Hyperlink documentationLink;
winrt::Windows::UI::Xaml::Documents::Hyperlink releaseNotesLink;
std::wstringstream aboutTextStream;
gettingStarted.Text(gettingStartedLabel);
documentation.Text(documentationLabel);
releaseNotes.Text(releaseNotesLabel);
winrt::Windows::Foundation::Uri gettingStartedUri{ gettingStartedUriValue };
winrt::Windows::Foundation::Uri documentationUri{ documentationUriValue };
winrt::Windows::Foundation::Uri releaseNotesUri{ releaseNotesUriValue };
gettingStartedLink.NavigateUri(gettingStartedUri);
documentationLink.NavigateUri(documentationUri);
releaseNotesLink.NavigateUri(releaseNotesUri);
gettingStartedLink.Inlines().Append(gettingStarted);
documentationLink.Inlines().Append(documentation);
releaseNotesLink.Inlines().Append(releaseNotes);
// Format our about text. It will look like the following:
// <Display Name>
// Version: <Major>.<Minor>.<Build>.<Revision>
// Getting Started
// Documentation
// Release Notes
aboutTextStream << packageName.c_str() << L"\n";
aboutTextStream << versionLabel.c_str() << L" ";
aboutTextStream << version.Major << L"." << version.Minor << L"." << version.Build << L"." << version.Revision;
aboutTextStream << version.Major << L"." << version.Minor << L"." << version.Build << L"." << version.Revision << L"\n";
winrt::hstring aboutText{ aboutTextStream.str() };
about.Text(aboutText);
const auto buttonText = resourceLoader.GetString(L"Ok");
gettingStartedLink.Foreground(blueBrush);
documentationLink.Foreground(blueBrush);
releaseNotesLink.Foreground(blueBrush);
Controls::TextBlock aboutTextBlock;
aboutTextBlock.Text(aboutText);
aboutTextBlock.Inlines().Append(about);
aboutTextBlock.Inlines().Append(gettingStartedLink);
aboutTextBlock.Inlines().Append(documentationLink);
aboutTextBlock.Inlines().Append(releaseNotesLink);
aboutTextBlock.IsTextSelectionEnabled(true);
_ShowDialog(winrt::box_value(title), aboutTextBlock, buttonText);
@@ -445,7 +424,12 @@ namespace winrt::TerminalApp::implementation
co_await winrt::resume_background();
const auto settingsPath = CascadiaSettings::GetSettingsPath();
ShellExecute(nullptr, L"open", settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
HINSTANCE res = ShellExecute(nullptr, nullptr, settingsPath.c_str(), nullptr, nullptr, SW_SHOW);
if (static_cast<int>(reinterpret_cast<uintptr_t>(res)) <= 32)
{
ShellExecute(nullptr, nullptr, L"notepad", settingsPath.c_str(), nullptr, SW_SHOW);
}
}
// Method Description:
@@ -467,7 +451,9 @@ namespace winrt::TerminalApp::implementation
void App::_FeedbackButtonOnClick(const IInspectable&,
const RoutedEventArgs&)
{
winrt::Windows::System::Launcher::LaunchUriAsync({ L"https://github.com/microsoft/Terminal/issues" });
const auto feedbackUriValue = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView().GetString(L"FeedbackUriValue");
winrt::Windows::System::Launcher::LaunchUriAsync({ feedbackUriValue });
}
Windows::UI::Xaml::Controls::Border App::GetDragBar() noexcept
@@ -518,6 +504,7 @@ namespace winrt::TerminalApp::implementation
bindings.ScrollDownPage([this]() { _ScrollPage(1); });
bindings.SwitchToTab([this](const auto index) { _SelectTab({ index }); });
bindings.OpenSettings([this]() { _OpenSettings(); });
bindings.ResizePane([this](const auto direction) { _ResizePane(direction); });
bindings.CopyText([this](const auto trimWhitespace) { _CopyText(trimWhitespace); });
bindings.PasteText([this]() { _PasteText(); });
}
@@ -761,7 +748,6 @@ namespace winrt::TerminalApp::implementation
void App::_ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme)
{
_root.RequestedTheme(newTheme);
_tabRow.RequestedTheme(newTheme);
}
UIElement App::GetRoot() noexcept
@@ -769,11 +755,6 @@ namespace winrt::TerminalApp::implementation
return _root;
}
UIElement App::GetTabs() noexcept
{
return _tabRow;
}
void App::_SetFocusedTabIndex(int tabIndex)
{
// GH#1117: This is a workaround because _tabView.SelectedIndex(tabIndex)
@@ -1033,6 +1014,20 @@ namespace winrt::TerminalApp::implementation
_tabs[focusedTabIndex]->Scroll(termHeight * delta);
}
// Method Description:
// - Attempt to move a separator between panes, as to resize each child on
// either size of the separator. See Pane::ResizePane for details.
// - Moves a separator on the currently focused tab.
// Arguments:
// - direction: The direction to move the separator in.
// Return Value:
// - <none>
void App::_ResizePane(const Direction& direction)
{
const auto focusedTabIndex = _GetFocusedTabIndex();
_tabs[focusedTabIndex]->ResizePane(direction);
}
// Method Description:
// - Copy text from the focused terminal to the Windows Clipboard
// Arguments:
@@ -1322,6 +1317,23 @@ namespace winrt::TerminalApp::implementation
focusedTab->AddVerticalSplit(realGuid, newControl);
}
// Method Description:
// - Called when our tab content size changes. This updates each tab with
// the new size, so they have a chance to update each of their panes with
// the new size.
// Arguments:
// - e: the SizeChangedEventArgs with the new size of the tab content area.
// Return Value:
// - <none>
void App::_OnContentSizeChanged(const IInspectable& /*sender*/, Windows::UI::Xaml::SizeChangedEventArgs const& e)
{
const auto newSize = e.NewSize();
for (auto& tab : _tabs)
{
tab->ResizeContent(newSize);
}
}
// Method Description:
// - Place `copiedData` into the clipboard as text. Triggered when a
// terminal control raises it's CopyToClipboard event.

View File

@@ -26,7 +26,6 @@ namespace winrt::TerminalApp::implementation
App();
Windows::UI::Xaml::UIElement GetRoot() noexcept;
Windows::UI::Xaml::UIElement GetTabs() noexcept;
// Gets the current dragglable area in the non client region of the top level window
Windows::UI::Xaml::Controls::Border GetDragBar() noexcept;
@@ -52,7 +51,7 @@ namespace winrt::TerminalApp::implementation
// ALSO: If you add any UIElements as roots here, make sure they're
// updated in _ApplyTheme. The two roots currently are _root and _tabRow
// (which is a root when the tabs are in the titlebar.)
Windows::UI::Xaml::Controls::Grid _root{ nullptr };
Windows::UI::Xaml::Controls::Control _root{ nullptr };
Microsoft::UI::Xaml::Controls::TabView _tabView{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabRow{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
@@ -122,12 +121,14 @@ namespace winrt::TerminalApp::implementation
// Todo: add more event implementations here
// MSFT:20641986: Add keybindings for New Window
void _ScrollPage(int delta);
void _ResizePane(const Direction& direction);
void _OnLoaded(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
void _OnTabClosing(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabClosingEventArgs& eventArgs);
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnContentSizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
void _RemoveTabViewItem(const IInspectable& tabViewItem);

View File

@@ -21,7 +21,6 @@ namespace TerminalApp
void LoadSettings();
Windows.UI.Xaml.UIElement GetRoot();
Windows.UI.Xaml.UIElement GetTabs();
Windows.UI.Xaml.Controls.Border GetDragBar{ get; };
Windows.Foundation.Point GetLaunchDimensions(UInt32 dpi);

View File

@@ -157,6 +157,18 @@ namespace winrt::TerminalApp::implementation
case ShortcutAction::SwitchToTab8:
_SwitchToTabHandlers(8);
return true;
case ShortcutAction::ResizePaneLeft:
_ResizePaneHandlers(Direction::Left);
return true;
case ShortcutAction::ResizePaneRight:
_ResizePaneHandlers(Direction::Right);
return true;
case ShortcutAction::ResizePaneUp:
_ResizePaneHandlers(Direction::Up);
return true;
case ShortcutAction::ResizePaneDown:
_ResizePaneHandlers(Direction::Down);
return true;
default:
return false;
@@ -238,5 +250,6 @@ namespace winrt::TerminalApp::implementation
DEFINE_EVENT(AppKeyBindings, ScrollUpPage, _ScrollUpPageHandlers, TerminalApp::ScrollUpPageEventArgs);
DEFINE_EVENT(AppKeyBindings, ScrollDownPage, _ScrollDownPageHandlers, TerminalApp::ScrollDownPageEventArgs);
DEFINE_EVENT(AppKeyBindings, OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
DEFINE_EVENT(AppKeyBindings, ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
// clang-format on
}

View File

@@ -60,6 +60,7 @@ namespace winrt::TerminalApp::implementation
DECLARE_EVENT(ScrollUpPage, _ScrollUpPageHandlers, TerminalApp::ScrollUpPageEventArgs);
DECLARE_EVENT(ScrollDownPage, _ScrollDownPageHandlers, TerminalApp::ScrollDownPageEventArgs);
DECLARE_EVENT(OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
DECLARE_EVENT(ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
// clang-format on
private:

View File

@@ -3,6 +3,14 @@
namespace TerminalApp
{
enum Direction
{
Left = 0,
Right,
Up,
Down
};
enum ShortcutAction
{
CopyText = 0,
@@ -41,6 +49,10 @@ namespace TerminalApp
ScrollDown,
ScrollUpPage,
ScrollDownPage,
ResizePaneLeft,
ResizePaneRight,
ResizePaneUp,
ResizePaneDown,
OpenSettings
};
@@ -64,6 +76,7 @@ namespace TerminalApp
delegate void ScrollUpPageEventArgs();
delegate void ScrollDownPageEventArgs();
delegate void OpenSettingsEventArgs();
delegate void ResizePaneEventArgs(Direction direction);
[default_interface]
runtimeclass AppKeyBindings : Microsoft.Terminal.Settings.IKeyBindings
@@ -93,5 +106,6 @@ namespace TerminalApp
event ScrollUpPageEventArgs ScrollUpPage;
event ScrollDownPageEventArgs ScrollDownPage;
event OpenSettingsEventArgs OpenSettings;
event ResizePaneEventArgs ResizePane;
}
}

View File

@@ -51,6 +51,10 @@ static constexpr std::string_view SwitchToTab8Key{ "switchToTab8" };
static constexpr std::string_view OpenSettingsKey{ "openSettings" };
static constexpr std::string_view SplitHorizontalKey{ "splitHorizontal" };
static constexpr std::string_view SplitVerticalKey{ "splitVertical" };
static constexpr std::string_view ResizePaneLeftKey{ "resizePaneLeft" };
static constexpr std::string_view ResizePaneRightKey{ "resizePaneRight" };
static constexpr std::string_view ResizePaneUpKey{ "resizePaneUp" };
static constexpr std::string_view ResizePaneDownKey{ "resizePaneDown" };
// Specifically use a map here over an unordered_map. We want to be able to
// iterate over these entries in-order when we're serializing the keybindings.
@@ -97,6 +101,10 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
{ SwitchToTab8Key, ShortcutAction::SwitchToTab8 },
{ SplitHorizontalKey, ShortcutAction::SplitHorizontal },
{ SplitVerticalKey, ShortcutAction::SplitVertical },
{ ResizePaneLeftKey, ShortcutAction::ResizePaneLeft },
{ ResizePaneRightKey, ShortcutAction::ResizePaneRight },
{ ResizePaneUpKey, ShortcutAction::ResizePaneUp },
{ ResizePaneDownKey, ShortcutAction::ResizePaneDown },
{ OpenSettingsKey, ShortcutAction::OpenSettings },
};

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
//
// Module Name:
// - Profile.hpp
// - AppKeyBindingsSerialization.h
//
// Abstract:
// - A couple helper functions for serializing/deserializing an AppKeyBindings

View File

@@ -49,6 +49,35 @@ ColorScheme _CreateCampbellScheme()
// clang-format off
ColorScheme _CreateVintageScheme()
{
// as per https://github.com/microsoft/terminal/issues/1781
ColorScheme vintageScheme { L"Vintage",
RGB(192, 192, 192),
RGB( 0, 0, 0) };
auto& vintageTable = vintageScheme.GetTable();
auto vintageSpan = gsl::span<COLORREF>(&vintageTable[0], gsl::narrow<ptrdiff_t>(COLOR_TABLE_SIZE));
vintageTable[0] = RGB( 0, 0, 0); // black
vintageTable[1] = RGB(128, 0, 0); // dark red
vintageTable[2] = RGB( 0, 128, 0); // dark green
vintageTable[3] = RGB(128, 128, 0); // dark yellow
vintageTable[4] = RGB( 0, 0, 128); // dark blue
vintageTable[5] = RGB(128, 0, 128); // dark magenta
vintageTable[6] = RGB( 0, 128, 128); // dark cyan
vintageTable[7] = RGB(192, 192, 192); // gray
vintageTable[8] = RGB(128, 128, 128); // dark gray
vintageTable[9] = RGB(255, 0, 0); // red
vintageTable[10] = RGB( 0, 255, 0); // green
vintageTable[11] = RGB(255, 255, 0); // yellow
vintageTable[12] = RGB( 0, 0, 255); // blue
vintageTable[13] = RGB(255, 0, 255); // magenta
vintageTable[14] = RGB( 0, 255, 255); // cyan
vintageTable[15] = RGB(255, 255, 255); // white
Utils::SetColorTableAlpha(vintageSpan, 0xff);
return vintageScheme;
}
ColorScheme _CreateOneHalfDarkScheme()
{
// First 8 dark colors per: https://github.com/sonph/onehalf/blob/master/putty/onehalf-dark.reg
@@ -179,6 +208,7 @@ ColorScheme _CreateSolarizedLightScheme()
void CascadiaSettings::_CreateDefaultSchemes()
{
_globals.GetColorSchemes().emplace_back(_CreateCampbellScheme());
_globals.GetColorSchemes().emplace_back(_CreateVintageScheme());
_globals.GetColorSchemes().emplace_back(_CreateOneHalfDarkScheme());
_globals.GetColorSchemes().emplace_back(_CreateOneHalfLightScheme());
_globals.GetColorSchemes().emplace_back(_CreateSolarizedDarkScheme());

View File

@@ -10,8 +10,6 @@ using namespace TerminalApp;
using namespace ::Microsoft::Console;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Microsoft::Terminal::TerminalControl;
using namespace winrt::TerminalApp;
using namespace winrt::Windows::Data::Json;
static constexpr std::string_view NameKey{ "name" };
static constexpr std::string_view TableKey{ "colors" };

View File

@@ -17,7 +17,6 @@ Author(s):
#pragma once
#include <winrt/Microsoft.Terminal.Settings.h>
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include <winrt/TerminalApp.h>
#include "../../inc/conattrs.hpp"
namespace TerminalApp

View File

@@ -23,6 +23,7 @@ static constexpr std::string_view InitialColsKey{ "initialCols" };
static constexpr std::string_view ShowTitleInTitlebarKey{ "showTerminalTitleInTitlebar" };
static constexpr std::string_view RequestedThemeKey{ "requestedTheme" };
static constexpr std::string_view ShowTabsInTitlebarKey{ "showTabsInTitlebar" };
static constexpr std::string_view WordDelimitersKey{ "wordDelimiters" };
static constexpr std::wstring_view LightThemeValue{ L"light" };
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
@@ -37,7 +38,8 @@ GlobalAppSettings::GlobalAppSettings() :
_initialCols{ DEFAULT_COLS },
_showTitleInTitlebar{ true },
_showTabsInTitlebar{ true },
_requestedTheme{ ElementTheme::Default }
_requestedTheme{ ElementTheme::Default },
_wordDelimiters{ DEFAULT_WORD_DELIMITERS }
{
}
@@ -105,6 +107,16 @@ void GlobalAppSettings::SetRequestedTheme(const ElementTheme requestedTheme) noe
_requestedTheme = requestedTheme;
}
std::wstring GlobalAppSettings::GetWordDelimiters() const noexcept
{
return _wordDelimiters;
}
void GlobalAppSettings::SetWordDelimiters(const std::wstring wordDelimiters) noexcept
{
_wordDelimiters = wordDelimiters;
}
#pragma region ExperimentalSettings
bool GlobalAppSettings::GetShowTabsInTitlebar() const noexcept
{
@@ -128,6 +140,7 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce
settings.KeyBindings(GetKeybindings());
settings.InitialRows(_initialRows);
settings.InitialCols(_initialCols);
settings.WordDelimiters(_wordDelimiters);
}
// Method Description:
@@ -146,6 +159,7 @@ Json::Value GlobalAppSettings::ToJson() const
jsonObject[JsonKey(AlwaysShowTabsKey)] = _alwaysShowTabs;
jsonObject[JsonKey(ShowTitleInTitlebarKey)] = _showTitleInTitlebar;
jsonObject[JsonKey(ShowTabsInTitlebarKey)] = _showTabsInTitlebar;
jsonObject[JsonKey(WordDelimitersKey)] = winrt::to_string(_wordDelimiters);
jsonObject[JsonKey(RequestedThemeKey)] = winrt::to_string(_SerializeTheme(_requestedTheme));
jsonObject[JsonKey(KeybindingsKey)] = AppKeyBindingsSerialization::ToJson(_keybindings);
@@ -191,6 +205,11 @@ GlobalAppSettings GlobalAppSettings::FromJson(const Json::Value& json)
result._showTabsInTitlebar = showTabsInTitlebar.asBool();
}
if (auto wordDelimiters{ json[JsonKey(WordDelimitersKey)] })
{
result._wordDelimiters = GetWstringFromJson(wordDelimiters);
}
if (auto requestedTheme{ json[JsonKey(RequestedThemeKey)] })
{
result._requestedTheme = _ParseTheme(GetWstringFromJson(requestedTheme));

View File

@@ -47,6 +47,9 @@ public:
bool GetShowTabsInTitlebar() const noexcept;
void SetShowTabsInTitlebar(const bool showTabsInTitlebar) noexcept;
std::wstring GetWordDelimiters() const noexcept;
void SetWordDelimiters(const std::wstring wordDelimiters) noexcept;
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme() const noexcept;
Json::Value ToJson() const;
@@ -68,6 +71,7 @@ private:
bool _showTitleInTitlebar;
bool _showTabsInTitlebar;
std::wstring _wordDelimiters;
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
static winrt::Windows::UI::Xaml::ElementTheme _ParseTheme(const std::wstring& themeString) noexcept;

View File

@@ -11,29 +11,40 @@
namespace winrt::TerminalApp::implementation
{
MinMaxCloseControl::MinMaxCloseControl(uint64_t hWnd) :
_window(reinterpret_cast<HWND>(hWnd))
MinMaxCloseControl::MinMaxCloseControl()
{
const winrt::Windows::Foundation::Uri resourceLocator{ L"ms-appx:///MinMaxCloseControl.xaml" };
winrt::Windows::UI::Xaml::Application::LoadComponent(*this, resourceLocator, winrt::Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation::Nested);
InitializeComponent();
}
uint64_t MinMaxCloseControl::ParentWindowHandle() const
{
return reinterpret_cast<uint64_t>(_window);
}
void MinMaxCloseControl::ParentWindowHandle(uint64_t handle)
{
_window = reinterpret_cast<HWND>(handle);
}
void MinMaxCloseControl::_OnMaximize(byte flag)
{
POINT point1 = {};
::GetCursorPos(&point1);
const LPARAM lParam = MAKELPARAM(point1.x, point1.y);
WINDOWPLACEMENT placement = { sizeof(placement) };
::GetWindowPlacement(_window, &placement);
if (placement.showCmd == SW_SHOWNORMAL)
if (_window)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateMaximized", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
}
else if (placement.showCmd == SW_SHOWMAXIMIZED)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateNormal", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
POINT point1 = {};
::GetCursorPos(&point1);
const LPARAM lParam = MAKELPARAM(point1.x, point1.y);
WINDOWPLACEMENT placement = { sizeof(placement) };
::GetWindowPlacement(_window, &placement);
if (placement.showCmd == SW_SHOWNORMAL)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateMaximized", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_MAXIMIZE | flag, lParam);
}
else if (placement.showCmd == SW_SHOWMAXIMIZED)
{
winrt::Windows::UI::Xaml::VisualStateManager::GoToState(this->Maximize(), L"WindowStateNormal", false);
::PostMessage(_window, WM_SYSCOMMAND, SC_RESTORE | flag, lParam);
}
}
}
@@ -49,7 +60,10 @@ namespace winrt::TerminalApp::implementation
void MinMaxCloseControl::Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
::PostMessage(_window, WM_SYSCOMMAND, SC_MINIMIZE | HTMINBUTTON, 0);
if (_window)
{
::PostMessage(_window, WM_SYSCOMMAND, SC_MINIMIZE | HTMINBUTTON, 0);
}
}
void MinMaxCloseControl::Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)

View File

@@ -13,16 +13,19 @@ namespace winrt::TerminalApp::implementation
{
struct MinMaxCloseControl : MinMaxCloseControlT<MinMaxCloseControl>
{
MinMaxCloseControl(uint64_t hWnd);
MinMaxCloseControl();
void Minimize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Maximize_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void Close_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void DragBar_DoubleTapped(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs const& e);
uint64_t ParentWindowHandle() const;
void ParentWindowHandle(uint64_t handle);
private:
void _OnMaximize(byte flag);
HWND _window = nullptr;
HWND _window{ nullptr }; // non-owning handle; should not be freed in the dtor.
};
}

View File

@@ -3,9 +3,11 @@
[default_interface]
runtimeclass MinMaxCloseControl : Windows.UI.Xaml.Controls.StackPanel
{
MinMaxCloseControl(UInt64 hParentWnd);
MinMaxCloseControl();
Windows.UI.Xaml.Controls.Grid Content{ get; };
Windows.UI.Xaml.Controls.Border DragBar{ get; };
UInt64 ParentWindowHandle;
}
}

View File

@@ -6,7 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Background="{ThemeResource SystemChromeLowColor}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Orientation="Horizontal"
@@ -18,12 +18,12 @@
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
<StaticResource x:Key="CaptionButtonBackground" ResourceKey="SystemControlBackgroundAltHighBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="Red"/>
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
@@ -31,12 +31,12 @@
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<x:Double x:Key="CaptionButtonStrokeWidth">1.0</x:Double>
<StaticResource x:Key="CaptionButtonBackground" ResourceKey="SystemControlBackgroundAltHighBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush"/>
<StaticResource x:Key="CaptionButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush"/>
<StaticResource x:Key="CaptionButtonStroke" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePointerOver" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<StaticResource x:Key="CaptionButtonStrokePressed" ResourceKey="SystemControlForegroundBaseHighBrush"/>
<SolidColorBrush x:Key="CaptionButtonBackground" Color="Transparent" />
<SolidColorBrush x:Key="CloseButtonBackgroundPointerOver" Color="Red"/>
<SolidColorBrush x:Key="CloseButtonStrokePointerOver" Color="White"/>
<SolidColorBrush x:Key="CloseButtonBackgroundPressed" Color="#f1707a"/>
@@ -130,7 +130,11 @@
</StackPanel.Resources>
<Grid x:Name="Content"></Grid>
<Border Height="36.0" MinWidth="160.0" x:Name="DragBar" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" DoubleTapped="DragBar_DoubleTapped"/>
<Border Height="36.0"
MinWidth="160.0"
x:Name="DragBar"
Background="{ThemeResource SystemChromeLowColor}"
DoubleTapped="DragBar_DoubleTapped"/>
<Button Height="36.0" Width="45.0" x:Name="Minimize" Style="{StaticResource CaptionButton}" Click="Minimize_Click"
AutomationProperties.Name="Minimize">
<Button.Resources>

View File

@@ -4,12 +4,15 @@
#include "pch.h"
#include "Pane.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Microsoft::Terminal::TerminalControl;
using namespace winrt::TerminalApp;
static const int PaneSeparatorSize = 4;
static const float Half = 0.50f;
Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) :
_control{ control },
@@ -36,6 +39,154 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
}
}
// Method Description:
// - Update the size of this pane. Resizes each of our columns so they have the
// same relative sizes, given the newSize.
// - Because we're just manually setting the row/column sizes in pixels, we have
// to be told our new size, we can't just use our own OnSized event, because
// that _won't fire when we get smaller_.
// Arguments:
// - newSize: the amount of space that this pane has to fill now.
// Return Value:
// - <none>
void Pane::ResizeContent(const Size& newSize)
{
const auto width = newSize.Width;
const auto height = newSize.Height;
_CreateRowColDefinitions(newSize);
if (_splitState == SplitState::Vertical)
{
const auto paneSizes = _GetPaneSizes(width);
const Size firstSize{ paneSizes.first, height };
const Size secondSize{ paneSizes.second, height };
_firstChild->ResizeContent(firstSize);
_secondChild->ResizeContent(secondSize);
}
else if (_splitState == SplitState::Horizontal)
{
const auto paneSizes = _GetPaneSizes(height);
const Size firstSize{ width, paneSizes.first };
const Size secondSize{ width, paneSizes.second };
_firstChild->ResizeContent(firstSize);
_secondChild->ResizeContent(secondSize);
}
}
// Method Description:
// - Adjust our child percentages to increase the size of one of our children
// and decrease the size of the other.
// - Adjusts the separation amount by 5%
// - Does nothing if the direction doesn't match our current split direction
// Arguments:
// - direction: the direction to move our separator. If it's down or right,
// we'll be increasing the size of the first of our children. Else, we'll be
// decreasing the size of our first child.
// Return Value:
// - false if we couldn't resize this pane in the given direction, else true.
bool Pane::_Resize(const Direction& direction)
{
if (!DirectionMatchesSplit(direction, _splitState))
{
return false;
}
float amount = .05f;
if (direction == Direction::Right || direction == Direction::Down)
{
amount = -amount;
}
// Make sure we're not making a pane explode here by resizing it to 0 characters.
const bool changeWidth = _splitState == SplitState::Vertical;
const Size actualSize{ gsl::narrow_cast<float>(_root.ActualWidth()),
gsl::narrow_cast<float>(_root.ActualHeight()) };
// actualDimension is the size in DIPs of this pane in the direction we're
// resizing.
auto actualDimension = changeWidth ? actualSize.Width : actualSize.Height;
actualDimension -= PaneSeparatorSize;
const auto firstMinSize = _firstChild->_GetMinSize();
const auto secondMinSize = _secondChild->_GetMinSize();
// These are the minimum amount of space we need for each of our children
const auto firstMinDimension = changeWidth ? firstMinSize.Width : firstMinSize.Height;
const auto secondMinDimension = changeWidth ? secondMinSize.Width : secondMinSize.Height;
const auto firstMinPercent = firstMinDimension / actualDimension;
const auto secondMinPercent = secondMinDimension / actualDimension;
// Make sure that the first pane doesn't get bigger than the space we need
// to reserve for the second.
const auto firstMaxPercent = 1.0f - secondMinPercent;
_firstPercent = std::clamp(_firstPercent.value() - amount, firstMinPercent, firstMaxPercent);
// Update the other child to fill the remaining percent
_secondPercent = 1.0f - _firstPercent.value();
// Resize our columns to match the new percentages.
ResizeContent(actualSize);
return true;
}
// Method Description:
// - Moves the separator between panes, as to resize each child on either size
// of the separator. Tries to move a separator in the given direction. The
// separator moved is the separator that's closest depth-wise to the
// currently focused pane, that's also in the correct direction to be moved.
// If there isn't such a separator, then this method returns false, as we
// couldn't handle the resize.
// Arguments:
// - direction: The direction to move the separator in.
// Return Value:
// - true if we or a child handled this resize request.
bool Pane::ResizePane(const Direction& direction)
{
// If we're a leaf, do nothing. We can't possibly have a descendant with a
// separator the correct direction.
if (_IsLeaf())
{
return false;
}
// Check if either our first or second child is the currently focused leaf.
// If it is, and the requested resize direction matches our separator, then
// we're the pane that needs to adjust its separator.
// If our separator is the wrong direction, then we can't handle it.
const bool firstIsFocused = _firstChild->_IsLeaf() && _firstChild->_lastFocused;
const bool secondIsFocused = _secondChild->_IsLeaf() && _secondChild->_lastFocused;
if (firstIsFocused || secondIsFocused)
{
return _Resize(direction);
}
else
{
// If neither of our children were the focused leaf, then recurse into
// our children and see if they can handle the resize.
// For each child, if it has a focused descendant, try having that child
// handle the resize.
// If the child wasn't able to handle the resize, it's possible that
// there were no descendants with a separator the correct direction. If
// our separator _is_ the correct direction, then we should be the pane
// to resize. Otherwise, just return false, as we couldn't handle it
// either.
if ((!_firstChild->_IsLeaf()) && _firstChild->_HasFocusedChild())
{
return _firstChild->ResizePane(direction) || _Resize(direction);
}
else if ((!_secondChild->_IsLeaf()) && _secondChild->_HasFocusedChild())
{
return _secondChild->ResizePane(direction) || _Resize(direction);
}
}
return false;
}
// Method Description:
// - Called when our attached control is closed. Triggers listeners to our close
// event, if we're a leaf pane.
@@ -415,6 +566,61 @@ void Pane::_SetupChildCloseHandlers()
});
}
// Method Description:
// - Sets up row/column definitions for this pane. There are three total
// row/cols. The middle one is for the separator. The first and third are for
// each of the child panes, and are given a size in pixels, based off the
// availiable space, and the percent of the space they respectively consume,
// which is stored in _firstPercent and _secondPercent.
// - Does nothing if our split state is currently set to SplitState::None
// Arguments:
// - rootSize: The dimensions in pixels that this pane (and its children should consume.)
// Return Value:
// - <none>
void Pane::_CreateRowColDefinitions(const Size& rootSize)
{
if (_splitState == SplitState::Vertical)
{
_root.ColumnDefinitions().Clear();
// Create three columns in this grid: one for each pane, and one for the separator.
auto separatorColDef = Controls::ColumnDefinition();
separatorColDef.Width(GridLengthHelper::Auto());
const auto paneSizes = _GetPaneSizes(rootSize.Width);
auto firstColDef = Controls::ColumnDefinition();
firstColDef.Width(GridLengthHelper::FromPixels(paneSizes.first));
auto secondColDef = Controls::ColumnDefinition();
secondColDef.Width(GridLengthHelper::FromPixels(paneSizes.second));
_root.ColumnDefinitions().Append(firstColDef);
_root.ColumnDefinitions().Append(separatorColDef);
_root.ColumnDefinitions().Append(secondColDef);
}
else if (_splitState == SplitState::Horizontal)
{
_root.RowDefinitions().Clear();
// Create three rows in this grid: one for each pane, and one for the separator.
auto separatorRowDef = Controls::RowDefinition();
separatorRowDef.Height(GridLengthHelper::Auto());
const auto paneSizes = _GetPaneSizes(rootSize.Height);
auto firstRowDef = Controls::RowDefinition();
firstRowDef.Height(GridLengthHelper::FromPixels(paneSizes.first));
auto secondRowDef = Controls::RowDefinition();
secondRowDef.Height(GridLengthHelper::FromPixels(paneSizes.second));
_root.RowDefinitions().Append(firstRowDef);
_root.RowDefinitions().Append(separatorRowDef);
_root.RowDefinitions().Append(secondRowDef);
}
}
// Method Description:
// - Initializes our UI for a new split in this pane. Sets up row/column
// definitions, and initializes the separator grid. Does nothing if our split
@@ -425,16 +631,13 @@ void Pane::_SetupChildCloseHandlers()
// - <none>
void Pane::_CreateSplitContent()
{
Size actualSize{ gsl::narrow_cast<float>(_root.ActualWidth()),
gsl::narrow_cast<float>(_root.ActualHeight()) };
_CreateRowColDefinitions(actualSize);
if (_splitState == SplitState::Vertical)
{
// Create three columns in this grid: one for each pane, and one for the separator.
auto separatorColDef = Controls::ColumnDefinition();
separatorColDef.Width(GridLengthHelper::Auto());
_root.ColumnDefinitions().Append(Controls::ColumnDefinition{});
_root.ColumnDefinitions().Append(separatorColDef);
_root.ColumnDefinitions().Append(Controls::ColumnDefinition{});
// Create the pane separator
_separatorRoot = Controls::Grid{};
_separatorRoot.Width(PaneSeparatorSize);
@@ -443,14 +646,6 @@ void Pane::_CreateSplitContent()
}
else if (_splitState == SplitState::Horizontal)
{
// Create three rows in this grid: one for each pane, and one for the separator.
auto separatorRowDef = Controls::RowDefinition();
separatorRowDef.Height(GridLengthHelper::Auto());
_root.RowDefinitions().Append(Controls::RowDefinition{});
_root.RowDefinitions().Append(separatorRowDef);
_root.RowDefinitions().Append(Controls::RowDefinition{});
// Create the pane separator
_separatorRoot = Controls::Grid{};
_separatorRoot.Height(PaneSeparatorSize);
@@ -507,7 +702,7 @@ void Pane::SplitVertical(const GUID& profile, const TermControl& control)
return;
}
_DoSplit(SplitState::Vertical, profile, control);
_Split(SplitState::Vertical, profile, control);
}
// Method Description:
@@ -535,7 +730,7 @@ void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
return;
}
_DoSplit(SplitState::Horizontal, profile, control);
_Split(SplitState::Horizontal, profile, control);
}
// Method Description:
@@ -547,7 +742,7 @@ void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Pane::_DoSplit(SplitState splitType, const GUID& profile, const TermControl& control)
void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl& control)
{
// Lock the create/close lock so that another operation won't concurrently
// modify our tree
@@ -559,6 +754,9 @@ void Pane::_DoSplit(SplitState splitType, const GUID& profile, const TermControl
_splitState = splitType;
_firstPercent = { Half };
_secondPercent = { Half };
_CreateSplitContent();
// Remove any children we currently have. We can't add the existing
@@ -585,4 +783,52 @@ void Pane::_DoSplit(SplitState splitType, const GUID& profile, const TermControl
_lastFocused = false;
}
// Method Description:
// - Gets the size in pixels of each of our children, given the full size they
// should fill. Accounts for the size of the separator that should be between
// them as well.
// Arguments:
// - fullSize: the amount of space in pixels that should be filled by our
// children and their separator
// Return Value:
// - a pair with the size of our first child and the size of our second child,
// respectively.
std::pair<float, float> Pane::_GetPaneSizes(const float& fullSize)
{
if (_IsLeaf())
{
THROW_HR(E_FAIL);
}
const auto sizeMinusSeparator = fullSize - PaneSeparatorSize;
const auto firstSize = sizeMinusSeparator * _firstPercent.value();
const auto secondSize = sizeMinusSeparator * _secondPercent.value();
return { firstSize, secondSize };
}
// Method Description:
// - Get the absolute minimum size that this pane can be resized to and still
// have 1x1 character visible, in each of its children. This includes the
// space needed for the separator.
// Arguments:
// - <none>
// Return Value:
// - The minimum size that this pane can be resized to and still have a visible
// character.
Size Pane::_GetMinSize() const
{
if (_IsLeaf())
{
return _control.MinimumSize();
}
else
{
const auto firstSize = _firstChild->_GetMinSize();
const auto secondSize = _secondChild->_GetMinSize();
const auto newWidth = firstSize.Width + secondSize.Width + (_splitState == SplitState::Vertical ? PaneSeparatorSize : 0);
const auto newHeight = firstSize.Height + secondSize.Height + (_splitState == SplitState::Horizontal ? PaneSeparatorSize : 0);
return { newWidth, newHeight };
}
}
DEFINE_EVENT(Pane, Closed, _closedHandlers, ConnectionClosedEventArgs);

View File

@@ -20,6 +20,7 @@
#pragma once
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include <winrt/TerminalApp.h>
#include "../../cascadia/inc/cppwinrt_utils.h"
class Pane : public std::enable_shared_from_this<Pane>
@@ -44,6 +45,8 @@ public:
void UpdateFocus();
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile);
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
bool ResizePane(const winrt::TerminalApp::Direction& direction);
void SplitHorizontal(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void SplitVertical(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
@@ -58,6 +61,8 @@ private:
std::shared_ptr<Pane> _firstChild{ nullptr };
std::shared_ptr<Pane> _secondChild{ nullptr };
SplitState _splitState{ SplitState::None };
std::optional<float> _firstPercent{ std::nullopt };
std::optional<float> _secondPercent{ std::nullopt };
bool _lastFocused{ false };
std::optional<GUID> _profile{ std::nullopt };
@@ -71,12 +76,52 @@ private:
bool _HasFocusedChild() const noexcept;
void _SetupChildCloseHandlers();
void _DoSplit(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void _Split(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void _CreateRowColDefinitions(const winrt::Windows::Foundation::Size& rootSize);
void _CreateSplitContent();
void _ApplySplitDefinitions();
bool _Resize(const winrt::TerminalApp::Direction& direction);
void _CloseChild(const bool closeFirst);
void _FocusFirstChild();
void _ControlClosedHandler();
std::pair<float, float> _GetPaneSizes(const float& fullSize);
winrt::Windows::Foundation::Size _GetMinSize() const;
// Function Description:
// - Returns true if the given direction can be used with the given split
// type.
// - This is used for pane resizing (which will need a pane separator
// that's perpendicular to the direction to be able to move the separator
// in that direction).
// - Additionally, it will be used for moving focus between panes, which
// again happens _across_ a separator.
// Arguments:
// - direction: The Direction to compare
// - splitType: The SplitState to compare
// Return Value:
// - true iff the direction is perpendicular to the splitType. False for
// SplitState::None.
static constexpr bool DirectionMatchesSplit(const winrt::TerminalApp::Direction& direction,
const SplitState& splitType)
{
if (splitType == SplitState::None)
{
return false;
}
else if (splitType == SplitState::Horizontal)
{
return direction == winrt::TerminalApp::Direction::Up ||
direction == winrt::TerminalApp::Direction::Down;
}
else if (splitType == SplitState::Vertical)
{
return direction == winrt::TerminalApp::Direction::Left ||
direction == winrt::TerminalApp::Direction::Right;
}
return false;
}
};

View File

@@ -9,8 +9,6 @@
using namespace TerminalApp;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::TerminalApp;
using namespace winrt::Windows::Data::Json;
using namespace ::Microsoft::Console;
static constexpr std::string_view NameKey{ "name" };

View File

@@ -213,4 +213,28 @@ void Tab::AddHorizontalSplit(const GUID& profile, TermControl& control)
_rootPane->SplitHorizontal(profile, control);
}
// Method Description:
// - Update the size of our panes to fill the new given size. This happens when
// the window is resized.
// Arguments:
// - newSize: the amount of space that the panes have to fill now.
// Return Value:
// - <none>
void Tab::ResizeContent(const winrt::Windows::Foundation::Size& newSize)
{
_rootPane->ResizeContent(newSize);
}
// Method Description:
// - Attempt to move a separator between panes, as to resize each child on
// either size of the separator. See Pane::ResizePane for details.
// Arguments:
// - direction: The direction to move the separator in.
// Return Value:
// - <none>
void Tab::ResizePane(const winrt::TerminalApp::Direction& direction)
{
_rootPane->ResizePane(direction);
}
DEFINE_EVENT(Tab, Closed, _closedHandlers, ConnectionClosedEventArgs);

View File

@@ -23,6 +23,8 @@ public:
void AddHorizontalSplit(const GUID& profile, winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void UpdateFocus();
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
void ResizePane(const winrt::TerminalApp::Direction& direction);
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile);
winrt::hstring GetFocusedTitle() const;

View File

@@ -1,7 +1,8 @@
<?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.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup>
<!-- cppwinrt.build.pre.props depends on these settings: -->
<!-- build a dll, not exe (Application) -->
@@ -18,85 +19,29 @@
</PropertyGroup>
<!-- ========================= XAML files ======================== -->
<ItemGroup>
<!-- HERE BE DRAGONS:
For any types that use XAML information, if their .idl, .cpp, and .h
aren't all marked DependentUpon the corresponding .xaml file,
XamlTypeInfo.g.h won't pick it up correctly.
-->
<ApplicationDefinition Include="App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
<!-- DON'T PUT XAML FILES HERE! Put them in TerminalAppLib.vcxproj -->
</ItemGroup>
<!-- When we add other user controls, they should go in here as so: -->
<!-- <ItemGroup>
<Page Include="MyUserControl.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup> -->
<!-- ========================= Headers ======================== -->
<ItemGroup>
<ClInclude Include="App.base.h" />
<ClInclude Include="MinMaxCloseControl.h">
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Tab.h" />
<ClInclude Include="Pane.h" />
<ClInclude Include="ColorScheme.h" />
<ClInclude Include="GlobalAppSettings.h" />
<ClInclude Include="Profile.h" />
<ClInclude Include="CascadiaSettings.h" />
<ClInclude Include="AppKeyBindingsSerialization.h" />
<ClInclude Include="KeyChordSerialization.h" />
<ClInclude Include="Utils.h" />
<!-- Only put headers for winrt types in here. Don't put other header files
in here - put them in TerminalAppLib.vcxproj instead! -->
<ClInclude Include="pch.h" />
<ClInclude Include="AppKeyBindings.h">
<DependentUpon>AppKeyBindings.idl</DependentUpon>
</ClInclude>
<ClInclude Include="App.h">
<DependentUpon>App.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="TerminalPage.h" />
<ClInclude Include="MinMaxCloseControl.h" />
<ClInclude Include="AppKeyBindings.h" />
<ClInclude Include="App.h" />
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
<ItemGroup>
<ClCompile Include="MinMaxCloseControl.cpp">
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
</ClCompile>
<Midl Include="MinMaxCloseControl.idl">
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<ClCompile Include="Tab.cpp" />
<ClCompile Include="Pane.cpp" />
<ClCompile Include="ColorScheme.cpp" />
<ClCompile Include="GlobalAppSettings.cpp" />
<ClCompile Include="Profile.cpp" />
<ClCompile Include="CascadiaSettings.cpp" />
<ClCompile Include="CascadiaSettingsSerialization.cpp" />
<ClCompile Include="AppKeyBindingsSerialization.cpp" />
<ClCompile Include="KeyChordSerialization.cpp" />
<ClCompile Include="Utils.cpp" />
<!-- Don't put source files in here - put them in TerminalAppLib.vcxproj instead! -->
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="AppKeyBindings.cpp">
<DependentUpon>AppKeyBindings.idl</DependentUpon>
</ClCompile>
<ClCompile Include="App.cpp">
<DependentUpon>App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
you want to use jsoncpp -->
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
<Midl Include="App.idl">
<DependentUpon>App.xaml</DependentUpon>
</Midl>
<Midl Include="AppKeyBindings.idl" />
<!-- DON'T PUT IDL FILES HERE! Put them in TerminalApp.vcxproj -->
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
@@ -113,16 +58,31 @@
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj">
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj">
<Project>{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}</Project>
<!-- The midl compiler however, _will_ aggregate our winmd dependencies
somehow. So make sure to only include top-level dependencies here (don't
include Settings and Connection, since Control will include them for us) -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
<!-- Reference TerminalAppLib here, so we can use it's TerminalApp.winmd as
our TerminalApp.winmd. This didn't work correctly in VS2017, you'd need to
manually reference the lib -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" >
<Private>true</Private>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
</ProjectReference>
<!-- This is needed to be able to reference the XamlApplication type. -->
</ItemGroup>
<ItemGroup>
<Page Include="MinMaxCloseControl.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<PropertyGroup>
<!-- A small helper for paths to the compiled cppwinrt projects -->
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
</PropertyGroup>
<PropertyGroup>
<!--
DON'T REDIRECT OUR OUTPUT.
@@ -140,15 +100,7 @@
</Link>
</ItemDefinitionGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
</Project>

View File

@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "TerminalPage.h"
#include "TerminalPage.g.cpp"
using namespace winrt;
using namespace Windows::UI::Xaml;
namespace winrt::TerminalApp::implementation
{
TerminalPage::TerminalPage()
{
InitializeComponent();
}
// Method Description:
// - Bound in the Xaml editor to the [+] button.
// Arguments:
// - sender
// - event arguments
void TerminalPage::OnNewTabButtonClick(IInspectable const&, Controls::SplitButtonClickEventArgs const&)
{
}
}

View File

@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "winrt/Microsoft.UI.Xaml.Controls.h"
#include "TerminalPage.g.h"
namespace winrt::TerminalApp::implementation
{
struct TerminalPage : TerminalPageT<TerminalPage>
{
TerminalPage();
void OnNewTabButtonClick(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::SplitButtonClickEventArgs const& args);
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct TerminalPage : TerminalPageT<TerminalPage, implementation::TerminalPage>
{
};
}

View File

@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
[default_interface]
runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page
{
TerminalPage();
}
}

View File

@@ -0,0 +1,49 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="TerminalApp.TerminalPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="TabRow" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<mux:TabView x:Name="TabView" Grid.Column="0" />
<SplitButton
x:Name="NewTabButton"
Grid.Column="1"
Click="OnNewTabButtonClick"
Background="{ThemeResource SystemChromeLowColor}"
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
<Viewbox MaxHeight="15"
MaxWidth="15">
<SymbolIcon Symbol="Add" />
</Viewbox>
</SplitButton>
<local:MinMaxCloseControl
x:Name="MinMaxCloseControl"
Grid.Column="3"
HorizontalAlignment="Right" />
</Grid>
<Grid x:Name="TabContent" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
</Page>

View File

@@ -0,0 +1,280 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<!-- ========================= CppWinRT Metadata ======================== -->
<PropertyGroup>
<ConfigurationType>StaticLibrary</ConfigurationType>
<SubSystem>Console</SubSystem>
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
<!--
This is an override that, puzzlingly, _forces XBF (XAML binary) embedding_.
We have to do this to overcome a layout issue in the WAP packaging project.
When we do this, the XBF ends up in resources.pri.
-->
<DisableEmbeddedXbf>false</DisableEmbeddedXbf>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<!-- ========================= XAML files ======================== -->
<ItemGroup>
<!-- HERE BE DRAGONS:
For any types that use XAML information, if their .idl and .h aren't
marked DependentUpon the corresponding .xaml file, XamlTypeInfo.g.h won't
pick it up correctly. -->
<ApplicationDefinition Include="..\App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
</ItemGroup>
<!-- When we add other user controls, they should go in here as so: -->
<ItemGroup>
<Page Include="../MinMaxCloseControl.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../TerminalPage.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<!-- ========================= Headers ======================== -->
<ItemGroup>
<ClInclude Include="../App.base.h" />
<ClInclude Include="../MinMaxCloseControl.h">
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../TerminalPage.h">
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../Tab.h" />
<ClInclude Include="../Pane.h" />
<ClInclude Include="../ColorScheme.h" />
<ClInclude Include="../GlobalAppSettings.h" />
<ClInclude Include="../Profile.h" />
<ClInclude Include="../CascadiaSettings.h" />
<ClInclude Include="../AppKeyBindingsSerialization.h" />
<ClInclude Include="../KeyChordSerialization.h" />
<ClInclude Include="../Utils.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="../AppKeyBindings.h" />
<ClInclude Include="../App.h" >
<DependentUpon>../App.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
<ItemGroup>
<ClCompile Include="../MinMaxCloseControl.cpp">
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../TerminalPage.cpp">
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../Tab.cpp" />
<ClCompile Include="../Pane.cpp" />
<ClCompile Include="../ColorScheme.cpp" />
<ClCompile Include="../GlobalAppSettings.cpp" />
<ClCompile Include="../Profile.cpp" />
<ClCompile Include="../CascadiaSettings.cpp" />
<ClCompile Include="../CascadiaSettingsSerialization.cpp" />
<ClCompile Include="../AppKeyBindingsSerialization.cpp" />
<ClCompile Include="../KeyChordSerialization.cpp" />
<ClCompile Include="../Utils.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="../AppKeyBindings.cpp" >
<DependentUpon>../AppKeyBindings.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../App.cpp" >
<DependentUpon>../App.xaml</DependentUpon>
</ClCompile>
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
you want to use jsoncpp -->
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
<!-- If you add idl files here, make sure to include their implementation's
header in TerminalApp.vcxproj (as well as in this file) -->
<Midl Include="../App.idl" >
<DependentUpon>../App.xaml</DependentUpon>
</Midl>
<Midl Include="../AppKeyBindings.idl" />
<Midl Include="../MinMaxCloseControl.idl">
<DependentUpon>../MinMaxCloseControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../TerminalPage.idl">
<DependentUpon>../TerminalPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
<None Include="../packages.config" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<!--
the packaging project won't recurse through our dependencies, you have to
make sure that if you add a cppwinrt dependency to any of these projects,
you also update all the consumers
-->
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
<!-- For whatever reason, we can't include the TerminalControl and
TerminalSettings projects' winmds via project references. So we'll have to
manually include the winmds as References below -->
</ItemGroup>
<PropertyGroup>
<!-- A small helper for paths to the compiled cppwinrt projects -->
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
</PropertyGroup>
<PropertyGroup>
<!-- This is a hack to get the ARM64 CI build working. See
https://github.com/Microsoft/msbuild/issues/3746 - it looks like MsBuild
just has a bug in it.-->
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>Warning</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
<ItemGroup>
<!-- Manually add references to each of our dependent winmds. Mark them as
private=false and CopyLocalSatelliteAssemblies=false, so that we don't
propogate them upwards (which can make referencing this project result in
duplicate type definitions)-->
<Reference Include="Microsoft.Terminal.Settings">
<HintPath>$(_BinRoot)TerminalSettings\Microsoft.Terminal.Settings.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.TerminalConnection">
<HintPath>$(_BinRoot)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.TerminalControl">
<HintPath>$(_BinRoot)TerminalControl\Microsoft.Terminal.TerminalControl.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
</ItemGroup>
<!-- ====================== Compiler & Linker Flags ===================== -->
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<!-- ========================= Globals ======================== -->
<PropertyGroup Label="Globals">
<ProjectGuid>{CA5CAD1A-9A12-429C-B551-8562EC954746}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>TerminalApp</RootNamespace>
<ProjectName>TerminalAppLib</ProjectName>
<TargetName>TerminalAppLib</TargetName>
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<PropertyGroup>
<!--
DON'T REDIRECT OUR OUTPUT.
Setting this will tell cppwinrt.build.post.props to copy our output from
the default OutDir up one level, so the wapproj will be able to find it.
-->
<NoOutputRedirection>true</NoOutputRedirection>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<!-- Manually include MUX here, instead of importing its targets file. We need
to reference its winmd, but very specifically with the
CopyLocalSatelliteAssemblies and Private properties set to false, as to not
have projects including us double-including MUX's .winmd. The following blob
is taken straight from the MUX build targets, with the afformentioned
changes.-->
<PropertyGroup>
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXRoot>$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\</_MUXRoot>
<_MUXAppRoot>$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\</_MUXAppRoot>
</PropertyGroup>
<ItemGroup>
<!-- Microsoft.UI.XAML -->
<Reference Include="$(_MUXRoot)lib\uap10.0\Microsoft.UI.Xaml.winmd">
<Implementation>Microsoft.UI.Xaml.dll</Implementation>
<IsWinMDFile>true</IsWinMDFile>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<Private>false</Private>
</Reference>
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.dll" />
<ReferenceCopyLocalPaths Include="$(_MUXRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.UI.Xaml.pri" />
<!-- Microsoft.UI.XAML.Application -->
<Reference Include="$(_MUXAppRoot)lib\uap10.0\Microsoft.Toolkit.Win32.UI.XamlHost.winmd">
<Implementation>Microsoft.Toolkit.Win32.UI.XamlHost.dll</Implementation>
<IsWinMDFile>true</IsWinMDFile>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<Private>false</Private>
</Reference>
<ReferenceCopyLocalPaths Include="$(_MUXAppRoot)lib\uap10.0\Microsoft.Toolkit.Win32.UI.XamlHost.*" />
<ReferenceCopyLocalPaths Include="$(_MUXAppRoot)runtimes\win10-$(Native-Platform)\native\Microsoft.Toolkit.Win32.UI.XamlHost.*" />
</ItemGroup>
<!-- End MUX import -->
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>
<!--
By default, the PRI file will contain resource paths beginning with the
project name. Since we enabled XBF embedding, this *also* includes App.xbf.
Well, App.xbf is hardcoded by the framework to be found at the resource ROOT.
To make that happen, we have to disable the prepending of the project name
to the App xaml files.
-->
<PropertyGroup>
<_GenerateProjectPriFileDependsOn>OpenConsolePlaceAppXbfAtRootOfResourceTree;$(_GenerateProjectPriFileDependsOn)</_GenerateProjectPriFileDependsOn>
</PropertyGroup>
<Target Name="OpenConsolePlaceAppXbfAtRootOfResourceTree" DependsOnTargets="GetPackagingOutputs">
<ItemGroup>
<_RelocatedAppXamlData Include="@(PackagingOutputs)" Condition="'%(Filename)' == 'App' and ('%(Extension)' == '.xaml' or '%(Extension)' == '.xbf')" />
<PackagingOutputs Remove="@(_RelocatedAppXamlData)" />
<PackagingOutputs Include="@(_RelocatedAppXamlData)">
<TargetPath>%(Filename)%(Extension)</TargetPath>
</PackagingOutputs>
</ItemGroup>
</Target>
</Project>

View File

@@ -19,14 +19,38 @@
#endif
#include <unknwn.h>
#include <hstring.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Documents.h"
#include <winrt/Microsoft.Toolkit.Win32.UI.XamlHost.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <winrt/Windows.System.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
#include <telemetry\ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
// JsonCpp
#include <json.h>
#include <shellapi.h>
#include <filesystem>

View File

@@ -2,5 +2,5 @@
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
</packages>

View File

@@ -7,49 +7,6 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <LibraryIncludes.h>
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <unknwn.h>
#include <hstring.h>
#include <winrt/coroutine.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <winrt/Microsoft.Toolkit.Win32.UI.XamlHost.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <winrt/Windows.System.h>
// Including TraceLogging essentials for the binary
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalWin32Provider);
#include <telemetry\ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
// JsonCpp
#include <json.h>
#include <shellapi.h>
#include <filesystem>
// This file can be empty - the pch.h in TerminalApp/lib does the heavy lifting
// of including all the headers we need. As this project is just a dll wrapper,
// we don't actually need anything in here.

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -8,15 +7,12 @@
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}</ProjectGuid>
<ProjectName>TerminalConnection</ProjectName>
<RootNamespace>Microsoft.Terminal.TerminalConnection</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="ConhostConnection.h">
<DependentUpon>ConhostConnection.idl</DependentUpon>
</ClInclude>
@@ -25,9 +21,6 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ConhostConnection.cpp">
<DependentUpon>ConhostConnection.idl</DependentUpon>
</ClCompile>
@@ -44,14 +37,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<!--
@@ -62,7 +52,6 @@
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj">
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<!--
@@ -72,7 +61,10 @@
-->
<NoOutputRedirection>true</NoOutputRedirection>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
</Project>
<Import Project="$(OpenConsoleDir)src\cascadia\SharedPch\SharedPch.props" />
</Project>

View File

@@ -10,13 +10,11 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="EchoConnection.cpp" />
<ClCompile Include="ConhostConnection.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="EchoConnection.h" />
<ClInclude Include="ConhostConnection.h" />
</ItemGroup>
@@ -26,10 +24,9 @@
<Midl Include="EchoConnection.idl" />
</ItemGroup>
<ItemGroup>
<None Include="TerminalConnection.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
</Project>
</Project>

View File

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

View File

@@ -1,16 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#pragma once
#include <LibraryIncludes.h>
// Must be included before any WinRT headers.
#include <unknwn.h>
#include "winrt/Windows.Foundation.h"
#include <Windows.h>

View File

@@ -39,7 +39,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_actualFont{ DEFAULT_FONT_FACE.c_str(), 0, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
_touchAnchor{ std::nullopt },
_leadingSurrogate{},
_cursorTimer{}
_cursorTimer{},
_lastMouseClick{},
_lastMouseClickPos{}
{
_Create();
}
@@ -93,7 +95,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
Controls::Grid::SetColumn(swapChainPanel, 0);
Controls::Grid::SetColumn(_scrollBar, 1);
_root = container;
Controls::Grid root{};
Controls::Image bgImageLayer{};
root.Children().Append(bgImageLayer);
root.Children().Append(container);
_root = root;
_bgImageLayer = bgImageLayer;
_swapChainPanel = swapChainPanel;
_controlRoot.Content(_root);
@@ -189,15 +198,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
// Method Description:
// - Set up the brush used to display the control's background.
// - Set up each layer's brush used to display the control's background.
// - Respects the settings for acrylic, background image and opacity from
// _settings.
// * Prioritizes the acrylic background if chosen, respecting acrylicOpacity
// from _settings.
// * If acrylic is not enabled and a backgroundImage is present, it is used,
// respecting the opacity and stretch mode settings from _settings.
// * Falls back to a solid color background from _settings if acrylic is not
// enabled and no background image is present.
// * If acrylic is not enabled, setup a solid color background, otherwise
// use bgcolor as acrylic's tint
// - Avoids image flickering and acrylic brush redraw if settings are changed
// but the appropriate brush is still in place.
// - Does not apply background color outside of acrylic mode;
@@ -242,23 +247,20 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_root.Background(acrylic);
}
}
else if (!_settings.BackgroundImage().empty())
else
{
Media::SolidColorBrush solidColor{};
_root.Background(solidColor);
}
if (!_settings.BackgroundImage().empty())
{
Windows::Foundation::Uri imageUri{ _settings.BackgroundImage() };
// Check if the existing brush is an image brush, and if not
// construct a new one
auto brush = _root.Background().try_as<Media::ImageBrush>();
if (brush == nullptr)
{
brush = Media::ImageBrush{};
}
// Check if the image brush is already pointing to the image
// in the modified settings; if it isn't (or isn't there),
// set a new image source for the brush
auto imageSource = brush.ImageSource().try_as<Media::Imaging::BitmapImage>();
auto imageSource = _bgImageLayer.Source().try_as<Media::Imaging::BitmapImage>();
if (imageSource == nullptr ||
imageSource.UriSource() == nullptr ||
@@ -269,23 +271,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// may well be both large and somewhere out on the
// internet.
Media::Imaging::BitmapImage image(imageUri);
brush.ImageSource(image);
_bgImageLayer.Source(image);
_bgImageLayer.HorizontalAlignment(HorizontalAlignment::Center);
_bgImageLayer.VerticalAlignment(VerticalAlignment::Center);
}
// Apply stretch and opacity settings
brush.Stretch(_settings.BackgroundImageStretchMode());
brush.Opacity(_settings.BackgroundImageOpacity());
// Apply brush if it isn't already there
if (_root.Background() != brush)
{
_root.Background(brush);
}
_bgImageLayer.Stretch(_settings.BackgroundImageStretchMode());
_bgImageLayer.Opacity(_settings.BackgroundImageOpacity());
}
else
{
Media::SolidColorBrush solidColor{};
_root.Background(solidColor);
_bgImageLayer.Source(nullptr);
}
}
@@ -308,37 +305,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
bgColor.B = B;
bgColor.A = 255;
if (_settings.UseAcrylic())
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
{
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
{
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
}
// If we're acrylic, we want to make sure that the default BG color
// is transparent, so we can see the acrylic effect on text with the
// default BG color.
_settings.DefaultBackground(ARGB(0, R, G, B));
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
}
else if (!_settings.BackgroundImage().empty())
else if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
{
// This currently applies no changes to the image background
// brush itself.
// Set the default background as transparent to prevent the
// DX layer from overwriting the background image
_settings.DefaultBackground(ARGB(0, R, G, B));
solidColor.Color(bgColor);
}
else
{
if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
{
solidColor.Color(bgColor);
}
_settings.DefaultBackground(RGB(R, G, B));
}
// Set the default background as transparent to prevent the
// DX layer from overwriting the background image or acrylic effect
_settings.DefaultBackground(ARGB(0, R, G, B));
});
}
@@ -537,6 +516,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_cursorTimer = std::nullopt;
}
// import value from WinUser (convert from milli-seconds to micro-seconds)
_multiClickTimer = GetDoubleClickTime() * 1000;
_gotFocusRevoker = _controlRoot.GotFocus(winrt::auto_revoke, { this, &TermControl::_GotFocusHandler });
_lostFocusRevoker = _controlRoot.LostFocus(winrt::auto_revoke, { this, &TermControl::_LostFocusHandler });
@@ -683,22 +665,46 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return;
}
const auto modifiers = args.KeyModifiers();
const auto altEnabled = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Menu);
const auto shiftEnabled = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift);
const auto modifiers = static_cast<uint32_t>(args.KeyModifiers());
// static_cast to a uint32_t because we can't use the WI_IsFlagSet
// macro directly with a VirtualKeyModifiers
const auto altEnabled = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Menu));
const auto shiftEnabled = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Shift));
if (point.Properties().IsLeftButtonPressed())
{
const auto cursorPosition = point.Position();
const auto terminalPosition = _GetTerminalPosition(cursorPosition);
// save location before rendering
_terminal->SetSelectionAnchor(terminalPosition);
// handle ALT key
_terminal->SetBoxSelection(altEnabled);
_renderer->TriggerSelection();
auto clickCount = _NumberOfClicks(cursorPosition, point.Timestamp());
// This formula enables the number of clicks to cycle properly between single-, double-, and triple-click.
// To increase the number of acceptable click states, simply increment MAX_CLICK_COUNT and add another if-statement
const unsigned int MAX_CLICK_COUNT = 3;
const auto multiClickMapper = clickCount > MAX_CLICK_COUNT ? ((clickCount + MAX_CLICK_COUNT - 1) % MAX_CLICK_COUNT) + 1 : clickCount;
if (multiClickMapper == 3)
{
_terminal->TripleClickSelection(terminalPosition);
_renderer->TriggerSelection();
}
else if (multiClickMapper == 2)
{
_terminal->DoubleClickSelection(terminalPosition);
_renderer->TriggerSelection();
}
else
{
// save location before rendering
_terminal->SetSelectionAnchor(terminalPosition);
_renderer->TriggerSelection();
_lastMouseClick = point.Timestamp();
_lastMouseClickPos = cursorPosition;
}
}
else if (point.Properties().IsRightButtonPressed())
{
@@ -814,9 +820,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
auto delta = args.GetCurrentPoint(_root).Properties().MouseWheelDelta();
// Get the state of the Ctrl & Shift keys
const auto modifiers = args.KeyModifiers();
const auto ctrlPressed = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Control);
const auto shiftPressed = WI_IsFlagSet(modifiers, VirtualKeyModifiers::Shift);
// static_cast to a uint32_t because we can't use the WI_IsFlagSet macro
// directly with a VirtualKeyModifiers
const auto modifiers = static_cast<uint32_t>(args.KeyModifiers());
const auto ctrlPressed = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Control));
const auto shiftPressed = WI_IsFlagSet(modifiers, static_cast<uint32_t>(VirtualKeyModifiers::Shift));
if (ctrlPressed && shiftPressed)
{
@@ -1080,7 +1088,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
// Method Description:
// - Process a resize event that was initiated by the user. This can either be due to the user resizing the window (causing the swapchain to resize) or due to the DPI changing (causing us to need to resize the buffer to match)
// - Process a resize event that was initiated by the user. This can either
// be due to the user resizing the window (causing the swapchain to
// resize) or due to the DPI changing (causing us to need to resize the
// buffer to match)
// Arguments:
// - newWidth: the new width of the swapchain, in pixels.
// - newHeight: the new height of the swapchain, in pixels.
@@ -1090,6 +1101,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
size.cx = static_cast<long>(newWidth);
size.cy = static_cast<long>(newHeight);
// Don't actually resize so small that a single character wouldn't fit
// in either dimension. The buffer really doesn't like being size 0.
if (size.cx < _actualFont.GetSize().X || size.cy < _actualFont.GetSize().Y)
{
return;
}
// Tell the dx engine that our window is now the new size.
THROW_IF_FAILED(_renderEngine->SetWindowSize(size));
@@ -1351,6 +1369,48 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
}
// Method Description:
// - Get the size of a single character of this control. The size is in
// DIPs. If you need it in _pixels_, you'll need to multiply by the
// current display scaling.
// Arguments:
// - <none>
// Return Value:
// - The dimensions of a single character of this control, in DIPs
winrt::Windows::Foundation::Size TermControl::CharacterDimensions() const
{
const auto fontSize = _actualFont.GetSize();
return { gsl::narrow_cast<float>(fontSize.X), gsl::narrow_cast<float>(fontSize.Y) };
}
// Method Description:
// - Get the absolute minimum size that this control can be resized to and
// still have 1x1 character visible. This includes the space needed for
// the scrollbar and the padding.
// Arguments:
// - <none>
// Return Value:
// - The minimum size that this terminal control can be resized to and still
// have a visible character.
winrt::Windows::Foundation::Size TermControl::MinimumSize() const
{
const auto fontSize = _actualFont.GetSize();
double width = fontSize.X;
double height = fontSize.Y;
// Reserve additional space if scrollbar is intended to be visible
if (_settings.ScrollState() == ScrollbarState::Visible)
{
width += _scrollBar.ActualWidth();
}
// Account for the size of any padding
auto thickness = _ParseThicknessFromPadding(_settings.Padding());
width += thickness.Left + thickness.Right;
height += thickness.Top + thickness.Bottom;
return { gsl::narrow_cast<float>(width), gsl::narrow_cast<float>(height) };
}
// Method Description:
// - Create XAML Thickness object based on padding props provided.
// Used for controlling the TermControl XAML Grid container's Padding prop.
@@ -1490,13 +1550,38 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return terminalPosition;
}
// clang-format off
// Method Description:
// - Returns the number of clicks that occurred (double and triple click support)
// Arguments:
// - clickPos: the (x,y) position of a given cursor (i.e.: mouse cursor).
// NOTE: origin (0,0) is top-left.
// - clickTime: the timestamp that the click occurred
// Return Value:
// - if the click is in the same position as the last click and within the timeout, the number of clicks within that time window
// - otherwise, 1
const unsigned int TermControl::_NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime)
{
// if click occurred at a different location or past the multiClickTimer...
Timestamp delta;
THROW_IF_FAILED(UInt64Sub(clickTime, _lastMouseClick, &delta));
if (clickPos != _lastMouseClickPos || delta > _multiClickTimer)
{
// exit early. This is a single click.
_multiClickCounter = 1;
}
else
{
_multiClickCounter++;
}
return _multiClickCounter;
}
// -------------------------------- WinRT Events ---------------------------------
// Winrt events need a method for adding a callback to the event and removing the callback.
// These macros will define them both for you.
DEFINE_EVENT(TermControl, TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs);
DEFINE_EVENT(TermControl, ConnectionClosed, _connectionClosedHandlers, TerminalControl::ConnectionClosedEventArgs);
DEFINE_EVENT(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::CopyToClipboardEventArgs);
DEFINE_EVENT(TermControl, TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs);
DEFINE_EVENT(TermControl, ConnectionClosed, _connectionClosedHandlers, TerminalControl::ConnectionClosedEventArgs);
DEFINE_EVENT(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::CopyToClipboardEventArgs);
DEFINE_EVENT(TermControl, ScrollPositionChanged, _scrollPositionChangedHandlers, TerminalControl::ScrollPositionChangedEventArgs);
// clang-format on

View File

@@ -44,6 +44,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void PasteTextFromClipboard();
void Close();
bool ShouldCloseOnExit() const noexcept;
Windows::Foundation::Size CharacterDimensions() const;
Windows::Foundation::Size MinimumSize() const;
void ScrollViewport(int viewTop);
void KeyboardScrollViewport(int viewTop);
@@ -71,6 +73,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
Windows::UI::Xaml::Controls::UserControl _controlRoot;
Windows::UI::Xaml::Controls::Grid _root;
Windows::UI::Xaml::Controls::Image _bgImageLayer;
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
Windows::UI::Xaml::Controls::Primitives::ScrollBar _scrollBar;
event_token _connectionOutputEventToken;
@@ -98,6 +101,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// viewport via touch input.
std::optional<winrt::Windows::Foundation::Point> _touchAnchor;
using Timestamp = uint64_t;
// imported from WinUser
// Used for PointerPoint.Timestamp Property (https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.pointerpoint.timestamp#Windows_UI_Input_PointerPoint_Timestamp)
Timestamp _multiClickTimer;
Timestamp _lastMouseClick;
unsigned int _multiClickCounter;
std::optional<winrt::Windows::Foundation::Point> _lastMouseClickPos;
// Event revokers -- we need to deregister ourselves before we die,
// lest we get callbacks afterwards.
winrt::Windows::UI::Xaml::Controls::Control::SizeChanged_revoker _sizeChangedRevoker;
@@ -144,6 +156,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
DWORD _GetPressedModifierKeys() const;
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);
};
}

View File

@@ -35,6 +35,8 @@ namespace Microsoft.Terminal.TerminalControl
void PasteTextFromClipboard();
void Close();
Boolean ShouldCloseOnExit { get; };
Windows.Foundation.Size CharacterDimensions { get; };
Windows.Foundation.Size MinimumSize { get; };
void ScrollViewport(Int32 viewTop);
void KeyboardScrollViewport(Int32 viewTop);

View File

@@ -16,15 +16,11 @@
<RootNamespace>Microsoft.Terminal.TerminalControl</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="TermControl.h">
<DependentUpon>TermControl.idl</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="TermControl.cpp">
<DependentUpon>TermControl.idl</DependentUpon>
</ClCompile>
@@ -44,9 +40,15 @@
<ProjectReference Include="..\..\renderer\dx\lib\dx.vcxproj" />
<ProjectReference Include="..\..\terminal\parser\lib\parser.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\terminal\input\lib\terminalinput.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj">
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalCore\lib\TerminalCore-lib.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" >
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</ProjectReference>
</ItemGroup>
<ItemDefinitionGroup>
<Link>
@@ -66,4 +68,5 @@
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cascadia\SharedPch\SharedPch.props" />
</Project>

View File

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

View File

@@ -133,6 +133,8 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting
_snapOnInput = settings.SnapOnInput();
_wordDelimiters = settings.WordDelimiters();
// TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we
// have a smaller scrollback. We should do this carefully - if the new buffer
// size is smaller than where the mutable viewport currently is, we'll want

View File

@@ -117,6 +117,8 @@ public:
#pragma region TextSelection
// These methods are defined in TerminalSelection.cpp
const bool IsSelectionActive() const noexcept;
void DoubleClickSelection(const COORD position);
void TripleClickSelection(const COORD position);
void SetSelectionAnchor(const COORD position);
void SetEndSelectionPosition(const COORD position);
void SetBoxSelection(const bool isEnabled) noexcept;
@@ -149,6 +151,7 @@ private:
bool _selectionActive;
SHORT _selectionAnchor_YOffset;
SHORT _endSelectionPosition_YOffset;
std::wstring _wordDelimiters;
std::shared_mutex _readWriteLock;
@@ -191,5 +194,9 @@ private:
std::vector<SMALL_RECT> _GetSelectionRects() const;
const SHORT _ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const;
const SHORT _ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const;
void _ExpandDoubleClickSelectionLeft(const COORD position);
void _ExpandDoubleClickSelectionRight(const COORD position);
const bool _isWordDelimiter(std::wstring_view cellChar) const;
const COORD _ConvertToBufferCell(const COORD viewportPos) const;
#pragma endregion
};

View File

@@ -91,7 +91,7 @@ const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHOR
{
// move off by highlighting the lead half too.
// alters position.X
_mutableViewport.DecrementInBounds(position);
_buffer->GetSize().DecrementInBounds(position);
}
return position.X;
}
@@ -116,7 +116,7 @@ const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHO
{
// move off by highlighting the trailing half too.
// alters position.X
_mutableViewport.IncrementInBounds(position);
_buffer->GetSize().IncrementInBounds(position);
}
return position.X;
}
@@ -130,6 +130,40 @@ const bool Terminal::IsSelectionActive() const noexcept
return _selectionActive;
}
// Method Description:
// - Select the sequence between delimiters defined in Settings
// Arguments:
// - position: the (x,y) coordinate on the visible viewport
void Terminal::DoubleClickSelection(const COORD position)
{
// if you double click a delimiter, just select that one cell
COORD positionWithOffsets = _ConvertToBufferCell(position);
const auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
if (_isWordDelimiter(cellChar))
{
SetSelectionAnchor(position);
return;
}
// scan leftwards until delimiter is found and
// set selection anchor to one right of that spot
_ExpandDoubleClickSelectionLeft(position);
// scan rightwards until delimiter is found and
// set endSelectionPosition to one left of that spot
_ExpandDoubleClickSelectionRight(position);
}
// Method Description:
// - Select the entire row of the position clicked
// Arguments:
// - position: the (x,y) coordinate on the visible viewport
void Terminal::TripleClickSelection(const COORD position)
{
SetSelectionAnchor({ 0, position.Y });
SetEndSelectionPosition({ _buffer->GetSize().RightInclusive(), position.Y });
}
// Method Description:
// - Record the position of the beginning of a selection
// Arguments:
@@ -213,3 +247,97 @@ const std::wstring Terminal::RetrieveSelectedTextFromBuffer(bool trimTrailingWhi
return result;
}
// Method Description:
// - expand the double click selection to the left (stopped by delimiter)
// Arguments:
// - position: viewport coordinate for selection
// Return Value:
// - update _selectionAnchor to new expanded location
void Terminal::_ExpandDoubleClickSelectionLeft(const COORD position)
{
// don't change the value if at/outside the boundary
if (position.X <= 0 || position.X >= _buffer->GetSize().RightInclusive())
{
return;
}
COORD positionWithOffsets = _ConvertToBufferCell(position);
const auto bufferViewport = _buffer->GetSize();
auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
while (positionWithOffsets.X != 0 && !_isWordDelimiter(cellChar))
{
bufferViewport.DecrementInBounds(positionWithOffsets);
cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
}
if (positionWithOffsets.X != 0 || _isWordDelimiter(cellChar))
{
// move off of delimiter to highlight properly
bufferViewport.IncrementInBounds(positionWithOffsets);
}
THROW_IF_FAILED(ShortSub(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
_selectionAnchor = positionWithOffsets;
_selectionAnchor_YOffset = gsl::narrow<SHORT>(_ViewStartIndex());
_selectionActive = true;
}
// Method Description:
// - expand the double click selection to the right (stopped by delimiter)
// Arguments:
// - position: viewport coordinate for selection
// Return Value:
// - update _endSelectionPosition to new expanded location
void Terminal::_ExpandDoubleClickSelectionRight(const COORD position)
{
// don't change the value if at/outside the boundary
if (position.X <= 0 || position.X >= _buffer->GetSize().RightInclusive())
{
return;
}
COORD positionWithOffsets = _ConvertToBufferCell(position);
const auto bufferViewport = _buffer->GetSize();
auto cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
while (positionWithOffsets.X != _buffer->GetSize().RightInclusive() && !_isWordDelimiter(cellChar))
{
bufferViewport.IncrementInBounds(positionWithOffsets);
cellChar = _buffer->GetCellDataAt(positionWithOffsets)->Chars();
}
if (positionWithOffsets.X != bufferViewport.RightInclusive() || _isWordDelimiter(cellChar))
{
// move off of delimiter to highlight properly
bufferViewport.DecrementInBounds(positionWithOffsets);
}
THROW_IF_FAILED(ShortSub(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
_endSelectionPosition = positionWithOffsets;
_endSelectionPosition_YOffset = gsl::narrow<SHORT>(_ViewStartIndex());
}
// Method Description:
// - check if buffer cell data contains delimiter for double click selection
// Arguments:
// - cellChar: the char saved to the buffer cell under observation
// Return Value:
// - true if cell data contains the delimiter.
const bool Terminal::_isWordDelimiter(std::wstring_view cellChar) const
{
return _wordDelimiters.find(cellChar) != std::wstring_view::npos;
}
// Method Description:
// - convert viewport position to the corresponding location on the buffer
// Arguments:
// - viewportPos: a coordinate on the viewport
// Return Value:
// - the corresponding location on the buffer
const COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
{
COORD positionWithOffsets = viewportPos;
THROW_IF_FAILED(ShortSub(viewportPos.Y, gsl::narrow<SHORT>(_scrollOffset), &positionWithOffsets.Y));
THROW_IF_FAILED(ShortAdd(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
return positionWithOffsets;
}

View File

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

View File

@@ -27,6 +27,7 @@ namespace Microsoft.Terminal.Settings
UInt32 CursorColor;
CursorStyle CursorShape;
UInt32 CursorHeight;
String WordDelimiters;
};
}

View File

@@ -20,6 +20,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorColor{ DEFAULT_CURSOR_COLOR },
_cursorShape{ CursorStyle::Vintage },
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },
_wordDelimiters{ DEFAULT_WORD_DELIMITERS },
_useAcrylic{ false },
_closeOnExit{ true },
_tintOpacity{ 0.5 },
@@ -135,6 +136,16 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_cursorHeight = value;
}
hstring TerminalSettings::WordDelimiters()
{
return _wordDelimiters;
}
void TerminalSettings::WordDelimiters(hstring const& value)
{
_wordDelimiters = value;
}
bool TerminalSettings::UseAcrylic()
{
return _useAcrylic;

View File

@@ -16,7 +16,6 @@
<RootNamespace>Microsoft.Terminal.Settings</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="KeyChord.h">
<DependentUpon>KeyChord.idl</DependentUpon>
</ClInclude>
@@ -25,9 +24,6 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="KeyChord.cpp">
<DependentUpon>KeyChord.idl</DependentUpon>
</ClCompile>
@@ -58,4 +54,5 @@
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cascadia\SharedPch\SharedPch.props" />
</Project>

View File

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

View File

@@ -1,22 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <LibraryIncludes.h>
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>

View File

@@ -45,6 +45,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
void CursorShape(winrt::Microsoft::Terminal::Settings::CursorStyle const& value) noexcept;
uint32_t CursorHeight();
void CursorHeight(uint32_t value);
hstring WordDelimiters();
void WordDelimiters(hstring const& value);
// ------------------------ End of Core Settings -----------------------
bool UseAcrylic();
@@ -94,6 +96,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
uint32_t _cursorColor;
Settings::CursorStyle _cursorShape;
uint32_t _cursorHeight;
hstring _wordDelimiters;
bool _useAcrylic;
bool _closeOnExit;

View File

@@ -36,6 +36,7 @@ namespace TerminalCoreUnitTests
uint32_t CursorColor() { return COLOR_WHITE; }
CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; }
uint32_t CursorHeight() { return 42UL; }
winrt::hstring WordDelimiters() { return winrt::to_hstring(DEFAULT_WORD_DELIMITERS.c_str()); }
// other implemented methods
uint32_t GetColorTableEntry(int32_t) const { return 123; }
@@ -50,6 +51,7 @@ namespace TerminalCoreUnitTests
void CursorColor(uint32_t) {}
void CursorShape(CursorStyle const&) noexcept {}
void CursorHeight(uint32_t) {}
void WordDelimiters(winrt::hstring) {}
// other unimplemented methods
void SetColorTableEntry(int32_t /* index */, uint32_t /* value */) {}

View File

@@ -89,6 +89,7 @@ public:
// do nothing.
break;
}
break;
}
case CM_UPDATE_TITLE:
{

View File

@@ -34,10 +34,17 @@ NonClientIslandWindow::~NonClientIslandWindow()
{
}
void NonClientIslandWindow::OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs eventArgs)
// Method Description:
// - Called when the app's size changes. When that happens, the size of the drag
// bar may have changed. If it has, we'll need to update the WindowRgn of the
// interop window.
// Arguments:
// - <unused>
// Return Value:
// - <none>
void NonClientIslandWindow::OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable /*sender*/, winrt::Windows::UI::Xaml::SizeChangedEventArgs /*eventArgs*/)
{
InvalidateRect(NULL, NULL, TRUE);
ForceResize();
_UpdateDragRegion();
}
void NonClientIslandWindow::OnAppInitialized(winrt::TerminalApp::App app)
@@ -101,8 +108,6 @@ void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
winrt::check_bool(SetWindowPos(_interopWindowHandle, HWND_BOTTOM, xPos, yPos, windowsWidth, windowsHeight, SWP_SHOWWINDOW));
if (_rootGrid)
{
winrt::Windows::Foundation::Size size{ (windowsWidth / scale) + 0.5f, (windowsHeight / scale) + 0.5f };
@@ -113,8 +118,53 @@ void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
_rootGrid.Arrange(finalRect);
}
// I'm not sure that HWND_BOTTOM is any different than HWND_TOP for us.
winrt::check_bool(SetWindowPos(_interopWindowHandle, HWND_BOTTOM, xPos, yPos, windowsWidth, windowsHeight, SWP_SHOWWINDOW));
}
// Method Description:
// - Update the region of our window that is the draggable area. This happens in
// response to a OnDragBarSizeChanged event. We'll calculate the areas of the
// window that we want to display XAML content in, and set the window region
// of our child xaml-island window to that region. That way, the parent window
// will still get NCHITTEST'ed _outside_ the XAML content area, for things
// like dragging and resizing.
// Arguments:
// - <none>
// Return Value:
// - <none>
void NonClientIslandWindow::_UpdateDragRegion()
{
if (_dragBar)
{
// TODO:GH#1897 This is largely duplicated from OnSize, and we should do
// better than that.
const auto windowRect = GetWindowRect();
const auto width = windowRect.right - windowRect.left;
const auto height = windowRect.bottom - windowRect.top;
const auto dpi = ::GetDpiForWindow(_window.get());
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
const auto dragX = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
// If we're maximized, we don't want to use the frame as our margins,
// instead we want to use the margins from the maximization. If we included
// the left&right sides of the frame in this calculation while maximized,
// you' have a few pixels of the window border on the sides while maximized,
// which most apps do not have.
const auto bordersWidth = _isMaximized ?
(_maximizedMargins.cxLeftWidth + _maximizedMargins.cxRightWidth) :
(dragX * 2);
const auto bordersHeight = _isMaximized ?
(_maximizedMargins.cyBottomHeight + _maximizedMargins.cyTopHeight) :
(dragY * 2);
const auto windowsWidth = width - bordersWidth;
const auto windowsHeight = height - bordersHeight;
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
const auto dragBarRect = GetDragAreaRect();
const auto nonClientHeight = dragBarRect.bottom - dragBarRect.top;
@@ -128,8 +178,6 @@ void NonClientIslandWindow::OnSize(const UINT width, const UINT height)
winrt::check_bool(CombineRgn(_dragBarRegion.get(), nonClientRegion.get(), clientRegion.get(), RGN_OR));
winrt::check_bool(SetWindowRgn(_interopWindowHandle, _dragBarRegion.get(), true));
}
winrt::check_hresult(_UpdateFrameMargins());
}
// Method Description:
@@ -229,10 +277,13 @@ MARGINS NonClientIslandWindow::GetFrameMargins() const noexcept
// - the HRESULT returned by DwmExtendFrameIntoClientArea.
[[nodiscard]] HRESULT NonClientIslandWindow::_UpdateFrameMargins() const noexcept
{
// Get the size of the borders we want to use. The sides and bottom will
// just be big enough for resizing, but the top will be as big as we need
// for the non-client content.
MARGINS margins = GetFrameMargins();
// Set frame margins with just a single pixel on the bottom. We don't
// really want a window frame at all - we're drawing all of it. We
// especially don't want a top margin - that's where the caption buttons
// are, and we're drawing those. So just set a single pixel on the bottom,
// because the method won't work with {0}.
MARGINS margins = { 0, 0, 0, 1 };
// Extend the frame into the client area.
return DwmExtendFrameIntoClientArea(_window.get(), &margins);
}
@@ -386,29 +437,33 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
}
break;
}
case WM_EXITSIZEMOVE:
{
ForceResize();
break;
}
case WM_NCACTIVATE:
case WM_NCPAINT:
case WM_PAINT:
{
if (!_dragBar)
{
return 0;
}
const auto hdc = wil::GetDC(_window.get());
PAINTSTRUCT ps{ 0 };
const auto hdc = wil::BeginPaint(_window.get(), &ps);
if (hdc.get())
{
const auto scale = GetCurrentDpiScale();
const auto dpi = ::GetDpiForWindow(_window.get());
// Get the dimensions of the drag borders for the sides of the window.
const auto dragY = ::GetSystemMetricsForDpi(SM_CYDRAG, dpi);
const auto dragX = ::GetSystemMetricsForDpi(SM_CXDRAG, dpi);
const auto xPos = _isMaximized ? _maximizedMargins.cxLeftWidth : dragX;
const auto yPos = _isMaximized ? _maximizedMargins.cyTopHeight : dragY;
// Create brush for borders, titlebar color.
const auto backgroundBrush = _dragBar.Background();
const auto backgroundSolidBrush = backgroundBrush.as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
const auto backgroundColor = backgroundSolidBrush.Color();
@@ -420,27 +475,34 @@ RECT NonClientIslandWindow::GetMaxWindowRectInPixels(const RECT* const prcSugges
const auto cx = windowRect.right - windowRect.left;
const auto cy = windowRect.bottom - windowRect.top;
// Fill in the _entire_ titlebar area.
RECT dragBarRect = {};
dragBarRect.left = xPos;
dragBarRect.right = xPos + cx;
dragBarRect.top = yPos;
dragBarRect.bottom = yPos + cy;
::FillRect(hdc.get(), &dragBarRect, _backgroundBrush.get());
// Draw the top window border
RECT clientRect = { 0, 0, cx, yPos };
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
// Draw the left window border
clientRect = { 0, 0, xPos, cy };
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
// Draw the bottom window border
clientRect = { 0, cy - yPos, cx, cy };
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
// Draw the right window border
clientRect = { cx - xPos, 0, cx, cy };
::FillRect(hdc.get(), &clientRect, _backgroundBrush.get());
RECT dragBarRect = GetDragAreaRect();
dragBarRect.left += xPos;
dragBarRect.right += xPos;
dragBarRect.bottom += yPos;
dragBarRect.top += yPos;
::FillRect(hdc.get(), &dragBarRect, _backgroundBrush.get());
}
return 0;
}
case WM_LBUTTONDOWN:
{
POINT point1 = {};
@@ -607,27 +669,19 @@ bool NonClientIslandWindow::_HandleWindowPosChanging(WINDOWPOS* const windowPos)
((suggestedWidth > maxWidth) ||
(suggestedHeight > maxHeight)))
{
auto offset = 0;
// Determine which side of the window to use for the offset
// calculation. If the taskbar is on the left or top of the screen,
// then the x or y coordinate of the work rect might not be 0.
// Check both, and use whichever is 0.
if (rcMaximum.left == 0)
{
offset = windowPos->x;
}
else if (rcMaximum.top == 0)
{
offset = windowPos->y;
}
const auto offsetX = offset;
const auto offsetY = offset;
RECT frame{};
// Calculate the maxmized window overhang by getting the size of the window frame.
// We use the style without WS_CAPTION otherwise the caption height is included.
// Only remove WS_DLGFRAME since WS_CAPTION = WS_DLGFRAME | WS_BORDER,
// but WS_BORDER is needed as it modifies the calculation of the width of the frame.
const auto targetStyle = windowStyle & ~WS_DLGFRAME;
AdjustWindowRectExForDpi(&frame, targetStyle, false, GetWindowExStyle(_window.get()), _currentDpi);
_maximizedMargins.cxRightWidth = -offset;
_maximizedMargins.cxLeftWidth = -offset;
_maximizedMargins.cyTopHeight = -offset;
_maximizedMargins.cyBottomHeight = -offset;
// Frame left and top will be negative
_maximizedMargins.cxLeftWidth = frame.left * -1;
_maximizedMargins.cyTopHeight = frame.top * -1;
_maximizedMargins.cxRightWidth = frame.right;
_maximizedMargins.cyBottomHeight = frame.bottom;
_isMaximized = true;
THROW_IF_FAILED(_UpdateFrameMargins());

View File

@@ -54,6 +54,7 @@ private:
void _HandleActivateWindow();
bool _HandleWindowPosChanging(WINDOWPOS* const windowPos);
void _UpdateDragRegion();
void OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs eventArgs);

View File

@@ -1,5 +1,10 @@
<?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 -->
@@ -22,7 +27,7 @@
Whenever you add new cppwinrt classes, make sure to add them here.
If you need help with the syntax, the generated AppxManifest.xml should have
the classes and files all listed in it.
TODO MSFT#21300206: Switch to automatically generating these.
-->
<file name="TerminalSettings.dll" hashalg="SHA1">

View File

@@ -17,6 +17,7 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@@ -24,18 +25,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@@ -44,11 +45,36 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ERROR_DIALOG_TITLE "Error"
IDS_ERROR_ARCHITECTURE_FORMAT
"Windows Terminal is designed to run on your system's native architecture (%s).\nYou are currently using the %s version.\n\nPlease use the version of Windows Terminal that matches your system's native architecture."
IDS_X86_ARCHITECTURE "i386"
END
STRINGTABLE
BEGIN
IDS_AMD64_ARCHITECTURE "AMD64"
IDS_ARM64_ARCHITECTURE "ARM64"
IDS_ARM_ARCHITECTURE "ARM"
IDS_UNKNOWN_ARCHITECTURE "Unknown"
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
@@ -65,4 +91,3 @@ END
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"

View File

@@ -1,145 +1,155 @@
<?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.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>
<SubSystem>Windows</SubSystem>
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
<ApplicationType>Windows Store</ApplicationType>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>WindowsTerminal</RootNamespace>
<ProjectName>WindowsTerminal</ProjectName>
<TargetName>WindowsTerminal</TargetName>
<!-- IMPORTANT! Xaml Islands only works on >= 17709 -->
<!-- IMPORTANT! cppwinrt.pre.props specifies 17134 -->
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<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>
<ClCompile>
<!-- Manually include the generated TerminalCore header's path, because
adding a project reference will confuse msbuild, because TerminalCore
isn't a dll, it's a lib, and cppwinrt won't include a lib's header -->
<AdditionalIncludeDirectories>"$(OpenConsoleDir)src\cascadia\TerminalCore\lib\Generated Files";%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>gdi32.lib;dwmapi.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<GenerateManifest>true</GenerateManifest>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<!-- Source Files -->
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="AppHost.h" />
<ClInclude Include="BaseWindow.h" />
<ClInclude Include="IslandWindow.h" />
<ClInclude Include="NonClientIslandWindow.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="main.cpp" />
<ClCompile Include="AppHost.cpp" />
<ClCompile Include="IslandWindow.cpp" />
<ClCompile Include="NonClientIslandWindow.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WindowsTerminal.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="WindowsTerminal.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<!-- Manually include the .pri files from the app project as content files. -->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\*.pri">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!-- Manually include the xbf files from the app project as content files -->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\*.xbf">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!--
The reason why this is needed for ARM64 is unknown,
If not added, the centenial package will fail to include the XamlHost dll.
-->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\Microsoft.Toolkit.Win32.UI.XamlHost.dll" Condition="'$(Platform)'=='ARM64'">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!--
The reason why this is needed for ARM64 is unknown,
If not added, the centenial package will fail to include the XamlHost dll.
-->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalApp\Microsoft.Toolkit.Win32.UI.XamlHost.dll" Condition="'$(Platform)'=='ARM64'">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!--
the packaging project wont recurse through our dependencies, you have to
make sure that if you add a cppwinrt dependency to any of these projects,
you also update all the consumers
-->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalApp\TerminalApp.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
</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>
<PropertyGroup>
<!-- DON'T REDIRECT OUR OUTPUT -->
<NoOutputRedirection>true</NoOutputRedirection>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>
<SubSystem>Windows</SubSystem>
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
<ApplicationType>Windows Store</ApplicationType>
</PropertyGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>WindowsTerminal</RootNamespace>
<ProjectName>WindowsTerminal</ProjectName>
<TargetName>WindowsTerminal</TargetName>
<!-- IMPORTANT! Xaml Islands only works on >= 17709 -->
<!-- IMPORTANT! cppwinrt.pre.props specifies 17134 -->
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<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>
<ClCompile>
<!-- Manually include the generated TerminalCore header's path, because
adding a project reference will confuse msbuild, because TerminalCore
isn't a dll, it's a lib, and cppwinrt won't include a lib's header -->
<AdditionalIncludeDirectories>"$(OpenConsoleDir)src\cascadia\TerminalCore\lib\Generated Files";%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>gdi32.lib;dwmapi.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<GenerateManifest>true</GenerateManifest>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<!-- Source Files -->
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="AppHost.h" />
<ClInclude Include="BaseWindow.h" />
<ClInclude Include="IslandWindow.h" />
<ClInclude Include="NonClientIslandWindow.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="AppHost.cpp" />
<ClCompile Include="IslandWindow.cpp" />
<ClCompile Include="NonClientIslandWindow.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WindowsTerminal.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="WindowsTerminal.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<!-- Manually include the .pri files from the app project as content files. -->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalAppLib\*.pri">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!-- Manually include the xbf files from the app project as content files -->
<NativeReferenceFile Include="$(OpenConsoleDir)$(Platform)\$(Configuration)\TerminalAppLib\*.xbf">
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</NativeReferenceFile>
<!--
the packaging project wont recurse through our dependencies, you have to
make sure that if you add a cppwinrt dependency to any of these projects,
you also update all the consumers
-->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettings\TerminalSettings.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<!-- Don't add a ProjectReference to TerminalApp here. If you do, the
packaging project will find the TerminalApp.pri from both the TerminalAppLib
and TerminalApp project, and we only want this lib project's pri file. We'll
manually add a reference to the TerminalApp winmd and dll below, because we
still need those. -->
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj" />
</ItemGroup>
<PropertyGroup>
<!-- A small helper for paths to the compiled cppwinrt projects -->
<_BinRoot Condition="'$(Platform)' != 'Win32'">$(OpenConsoleDir)$(Platform)\$(Configuration)\</_BinRoot>
<_BinRoot Condition="'$(Platform)' == 'Win32'">$(OpenConsoleDir)$(Configuration)\</_BinRoot>
</PropertyGroup>
<ItemGroup>
<!-- Manually reference TerminalApp, since we can't use a ProjectReference. -->
<Reference Include="TerminalApp">
<HintPath>$(_BinRoot)\TerminalApp\TerminalApp.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<ReferenceCopyLocalPaths Include="$(_BinRoot)\TerminalApp\TerminalApp.dll" />
</ItemGroup>
<!--
This ItemGroup and the Globals PropertyGroup below it are required in order
to enable F5 debugging for the unpackaged application
-->
<ItemGroup>
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_general.xml" />
<PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\debugger_local_windows.xml" />
</ItemGroup>
<PropertyGroup Label="Globals">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<!-- DON'T REDIRECT OUR OUTPUT -->
<NoOutputRedirection>true</NoOutputRedirection>
</PropertyGroup>
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" />
<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>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />
</Target>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.1\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
</Project>
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets'))" />
</Target>
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="$(OpenConsoleDir)src\cascadia\SharedPch\SharedPch.props" />
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190521.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.0.0-preview6.2\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.0-rc\build\native\Microsoft.VCRTForwarders.140.targets')" />
</Project>

View File

@@ -3,6 +3,7 @@
#include "pch.h"
#include "AppHost.h"
#include "resource.h"
using namespace winrt;
using namespace Windows::UI;
@@ -10,8 +11,94 @@ using namespace Windows::UI::Composition;
using namespace Windows::UI::Xaml::Hosting;
using namespace Windows::Foundation::Numerics;
// Routine Description:
// - Retrieves the string resource from the current module with the given ID
// from the resources files. See resource.h and the .rc definitions for valid IDs.
// Arguments:
// - id - Resource ID
// Return Value:
// - String resource retrieved from that ID.
static std::wstring GetStringResource(const UINT id)
{
// Calling LoadStringW with a pointer-sized storage and no length will return a read-only pointer
// directly to the resource data instead of copying it immediately into a buffer.
LPWSTR readOnlyResource = nullptr;
const auto length = LoadStringW(wil::GetModuleInstanceHandle(),
id,
reinterpret_cast<LPWSTR>(&readOnlyResource),
0);
// However, the pointer and length given are NOT guaranteed to be zero-terminated
// and most uses of this data will probably want a zero-terminated string.
// So we're going to construct and return a std::wstring copy from the pointer/length
// since those are certainly zero-terminated.
return { readOnlyResource, gsl::narrow<size_t>(length) };
}
// Routine Description:
// - Takes an image architecture and locates a string resource that maps to that architecture.
// Arguments:
// - imageArchitecture - An IMAGE_FILE_MACHINE architecture enum value
// - See https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
// Return Value:
// - A string value representing the human-readable name of this architecture.
static std::wstring ImageArchitectureToString(USHORT imageArchitecture)
{
// clang-format off
const auto id = imageArchitecture == IMAGE_FILE_MACHINE_I386 ? IDS_X86_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_AMD64 ? IDS_AMD64_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_ARM64 ? IDS_ARM64_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_ARM ? IDS_ARM_ARCHITECTURE :
IDS_UNKNOWN_ARCHITECTURE;
// clang-format on
return GetStringResource(id);
}
// Routine Description:
// - Blocks the user from launching the application with a message box dialog and early exit
// if the process architecture doesn't match the system platform native architecture.
// - This is because the conhost.exe must match the condrv.sys on the system and the PTY
// infrastructure that powers everything won't work if we have a mismatch.
// Arguments:
// - <none>
// Return Value:
// - <none>
static void EnsureNativeArchitecture()
{
USHORT processMachine{};
USHORT nativeMachine{};
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
if (processMachine != IMAGE_FILE_MACHINE_UNKNOWN && processMachine != nativeMachine)
{
const auto formatPattern = GetStringResource(IDS_ERROR_ARCHITECTURE_FORMAT);
const auto nativeArchitecture = ImageArchitectureToString(nativeMachine);
const auto processArchitecture = ImageArchitectureToString(processMachine);
const auto lengthRequired = _scwprintf(formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
const auto bufferSize = lengthRequired + 1;
std::wstring buffer;
buffer.resize(bufferSize);
swprintf_s(buffer.data(), buffer.size(), formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
MessageBoxW(nullptr,
buffer.data(),
GetStringResource(IDS_ERROR_DIALOG_TITLE).data(),
MB_OK | MB_ICONERROR);
ExitProcess(0);
}
}
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
// Block the user from starting if they launched the incorrect architecture version of the project.
// This should only be applicable to developer versions. The package installation process
// should choose and install the correct one from the bundle.
EnsureNativeArchitecture();
// Make sure to call this so we get WM_POINTER messages.
EnableMouseInPointer(true);

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.1" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.0.0-preview6.2" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.2.190611001-prerelease" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.0-rc" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.190417.3" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190521.3" targetFramework="native" />
</packages>

View File

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

View File

@@ -1,16 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Cascadia.EXE.rc
// Used by WindowsTerminal.rc
//
#define IDI_APPICON 101
#define IDS_ERROR_DIALOG_TITLE 105
#define IDS_ERROR_ARCHITECTURE_FORMAT 110
#define IDS_X86_ARCHITECTURE 111
#define IDS_AMD64_ARCHITECTURE 112
#define IDS_ARM64_ARCHITECTURE 113
#define IDS_ARM_ARCHITECTURE 114
#define IDS_UNKNOWN_ARCHITECTURE 115
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#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
#define IDI_APPICON 101

View File

@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "../TerminalApp/ColorScheme.h"
using namespace Microsoft::Console;
using namespace TerminalApp;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
namespace TerminalAppUnitTests
{
class JsonTests
{
BEGIN_TEST_CLASS(JsonTests)
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
END_TEST_CLASS()
TEST_METHOD(ParseInvalidJson);
TEST_METHOD(ParseSimpleColorScheme);
TEST_CLASS_SETUP(ClassSetup)
{
reader = std::unique_ptr<Json::CharReader>(Json::CharReaderBuilder::CharReaderBuilder().newCharReader());
return true;
}
Json::Value VerifyParseSucceeded(std::string content);
void VerifyParseFailed(std::string content);
private:
std::unique_ptr<Json::CharReader> reader;
};
Json::Value JsonTests::VerifyParseSucceeded(std::string content)
{
Json::Value root;
std::string errs;
const bool parseResult = reader->parse(content.c_str(), content.c_str() + content.size(), &root, &errs);
VERIFY_IS_TRUE(parseResult, winrt::to_hstring(errs).c_str());
return root;
}
void JsonTests::VerifyParseFailed(std::string content)
{
Json::Value root;
std::string errs;
const bool parseResult = reader->parse(content.c_str(), content.c_str() + content.size(), &root, &errs);
VERIFY_IS_FALSE(parseResult);
}
void JsonTests::ParseInvalidJson()
{
const std::string badJson{ "{ foo : bar : baz }" };
VerifyParseFailed(badJson);
}
void JsonTests::ParseSimpleColorScheme()
{
const std::string campbellScheme{ "{"
"\"background\" : \"#0C0C0C\","
"\"black\" : \"#0C0C0C\","
"\"blue\" : \"#0037DA\","
"\"brightBlack\" : \"#767676\","
"\"brightBlue\" : \"#3B78FF\","
"\"brightCyan\" : \"#61D6D6\","
"\"brightGreen\" : \"#16C60C\","
"\"brightPurple\" : \"#B4009E\","
"\"brightRed\" : \"#E74856\","
"\"brightWhite\" : \"#F2F2F2\","
"\"brightYellow\" : \"#F9F1A5\","
"\"cyan\" : \"#3A96DD\","
"\"foreground\" : \"#F2F2F2\","
"\"green\" : \"#13A10E\","
"\"name\" : \"Campbell\","
"\"purple\" : \"#881798\","
"\"red\" : \"#C50F1F\","
"\"white\" : \"#CCCCCC\","
"\"yellow\" : \"#C19C00\""
"}" };
const auto schemeObject = VerifyParseSucceeded(campbellScheme);
auto scheme = ColorScheme::FromJson(schemeObject);
VERIFY_ARE_EQUAL(L"Campbell", scheme.GetName());
VERIFY_ARE_EQUAL(ARGB(0, 0xf2, 0xf2, 0xf2), scheme.GetForeground());
VERIFY_ARE_EQUAL(ARGB(0, 0x0c, 0x0c, 0x0c), scheme.GetBackground());
std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable;
auto campbellSpan = gsl::span<COLORREF>(&expectedCampbellTable[0], gsl::narrow<ptrdiff_t>(COLOR_TABLE_SIZE));
Utils::InitializeCampbellColorTable(campbellSpan);
for (size_t i = 0; i < expectedCampbellTable.size(); i++)
{
const auto& expected = expectedCampbellTable.at(i);
const auto& actual = scheme.GetTable().at(i);
VERIFY_ARE_EQUAL(expected, actual);
}
}
}

View File

@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "../TerminalApp/ColorScheme.h"
using namespace Microsoft::Console;
using namespace TerminalApp;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
namespace TerminalAppUnitTests
{
// Unfortunately, these tests _WILL NOT_ work in our CI, until we have a lab
// machine available that can run Windows version 18362. Until then, these
// tests will be commented out. GH#1012 should move our CI to that version.
// When that happens, these tests can be re-added.
// class SettingsTests
// {
// // Use a custom manifest to ensure that we can activate winrt types from
// // our test. This property will tell taef to manually use this as the
// // sxs manifest during this test class. It includes all the cppwinrt
// // types we've defined, so if your test is crashing for an unknown
// // reason, make sure it's included in that file.
// // If you want to do anything XAML-y, you'll need to run yor test in a
// // packaged context. See TabTests.cpp for more details on that.
// BEGIN_TEST_CLASS(SettingsTests)
// TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
// END_TEST_CLASS()
// TEST_METHOD(TryCreateWinRTType);
// };
// void SettingsTests::TryCreateWinRTType()
// {
// winrt::Microsoft::Terminal::Settings::TerminalSettings settings{};
// VERIFY_IS_NOT_NULL(settings);
// auto oldFontSize = settings.FontSize();
// settings.FontSize(oldFontSize + 5);
// auto newFontSize = settings.FontSize();
// VERIFY_ARE_NOT_EQUAL(oldFontSize, newFontSize);
// }
}

View File

@@ -0,0 +1,112 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "../TerminalApp/ColorScheme.h"
#include "../TerminalApp/Tab.h"
using namespace Microsoft::Console;
using namespace TerminalApp;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
namespace TerminalAppUnitTests
{
// Unfortunately, these tests _WILL NOT_ work in our CI, until we have a lab
// machine available that can run Windows version 18362. Until then, these
// tests will be commented out. GH#1012 should move our CI to that version.
// When that happens, these tests can be re-added.
// class TabTests
// {
// // For this set of tests, we need to activate some XAML content. To do
// // that, we need to be able to activate Xaml Islands(XI), using the Xaml
// // Hosting APIs. Because XI looks at the manifest of the exe running, we
// // can't just use the TerminalApp.Unit.Tests.manifest as our
// // ActivationContext. XI is going to inspect `te.exe`s manifest to try
// // and find the maxversiontested property, but te.exe hasn't set that.
// // Instead, this test will run as a UAP application, as a packaged
// // centenial (win32) app. We'll specify our own AppxManifest, so that
// // we'll be able to also load all the dll's for the types we've defined
// // (and want to use here). This does come with a minor caveat, as
// // deploying the appx takes a bit, so use sparingly (though it will
// // deploy once per class when used like this.)
// BEGIN_TEST_CLASS(TabTests)
// TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
// TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TerminalApp.Unit.Tests.AppxManifest.xml")
// END_TEST_CLASS()
// // These four tests act as canary tests. If one of them fails, then they
// // can help you identify if something much lower in the stack has
// // failed.
// TEST_METHOD(TryInitXamlIslands);
// TEST_METHOD(TryCreateLocalWinRTType);
// TEST_METHOD(TryCreateXamlObjects);
// TEST_METHOD(TryCreateTab);
// TEST_CLASS_SETUP(ClassSetup)
// {
// winrt::init_apartment(winrt::apartment_type::single_threaded);
// // Initialize the Xaml Hosting Manager
// _manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
// _source = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
// return true;
// }
// private:
// winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager _manager{ nullptr };
// winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source{ nullptr };
// };
// void TabTests::TryInitXamlIslands()
// {
// // Ensures that XAML Islands was initialized correctly
// VERIFY_IS_NOT_NULL(_manager);
// VERIFY_IS_NOT_NULL(_source);
// }
// void TabTests::TryCreateLocalWinRTType()
// {
// // Verify we can create a WinRT type we authored
// // Just creating it is enough to know that everything is working.
// winrt::Microsoft::Terminal::Settings::TerminalSettings settings{};
// VERIFY_IS_NOT_NULL(settings);
// auto oldFontSize = settings.FontSize();
// settings.FontSize(oldFontSize + 5);
// auto newFontSize = settings.FontSize();
// VERIFY_ARE_NOT_EQUAL(oldFontSize, newFontSize);
// }
// void TabTests::TryCreateXamlObjects()
// {
// // Verify we can create a some XAML objects
// // Just creating all of them is enough to know that everything is working.
// winrt::Windows::UI::Xaml::Controls::UserControl controlRoot;
// VERIFY_IS_NOT_NULL(controlRoot);
// winrt::Windows::UI::Xaml::Controls::Grid root;
// VERIFY_IS_NOT_NULL(root);
// winrt::Windows::UI::Xaml::Controls::SwapChainPanel swapChainPanel;
// VERIFY_IS_NOT_NULL(swapChainPanel);
// winrt::Windows::UI::Xaml::Controls::Primitives::ScrollBar scrollBar;
// VERIFY_IS_NOT_NULL(scrollBar);
// }
// void TabTests::TryCreateTab()
// {
// // Just try creating all of:
// // 1. one of our pure c++ types (Profile)
// // 2. one of our c++winrt types (TermControl)
// // 3. one of our types that uses MUX/Xaml (Tab).
// // Just creating all of them is enough to know that everything is working.
// const auto profileGuid{ Utils::CreateGuid() };
// winrt::Microsoft::Terminal::TerminalControl::TermControl term{};
// VERIFY_IS_NOT_NULL(term);
// auto newTab = std::make_shared<Tab>(profileGuid, term);
// VERIFY_IS_NOT_NULL(newTab);
// }
}

View File

@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap">
<!-- This file is used as the Appxmanifest for tests that _need_ to run in a
packaged environment. It will be copied to the test's OutDir as part of the
PostBuid step. It's highly similar to the "PackagedCwaFullTrust" manifest that
TAEF ships with, with the following modifications:
1. All of our winrt types are included in this manifest, including types from
MUX.dll. Should this list of types ever change, we'll need to manually
update this file. The easiest way of doing that is deploying the app from
VS, then copying the Extensions from the Appxmandifest.xml that's generated
under `src/cascadia/CascadiaPackage/bin/$(platform)/$(configuration)/appx`.
2. We also _NEED_ the two vclibs listed under the `PackageDependency` block.
If your test fails for whatever reason, it's likely possible you're testing a
type that's _not_ included in this file for some reason. So, here be dragons. -->
<Identity Name="TerminalApp.Unit.Tests.Package"
ProcessorArchitecture="neutral"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="1.0.0.0"
ResourceId="en-us" />
<Properties>
<DisplayName>TerminalApp.Unit.Tests.Package Host Process</DisplayName>
<PublisherDisplayName>Microsoft Corp.</PublisherDisplayName>
<Logo>taef.png</Logo>
<Description>TAEF Packaged Cwa FullTrust Application Host Process</Description>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.27023.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
<PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.27027.1" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
</Dependencies>
<Resources>
<Resource Language="en-us" />
</Resources>
<Applications>
<Application Id="TE.ProcessHost" Executable="TE.ProcessHost.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="TAEF Packaged Cwa FullTrust Application Host Process" Square150x150Logo="taef.png" Square44x44Logo="taef.png" Description="TAEF Packaged Cwa Application Host Process" BackgroundColor="#222222">
<uap:SplashScreen Image="taef.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TerminalSettings.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.KeyChord" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.Terminal.Settings.TerminalSettings" ThreadingModel="both" />
</InProcessServer>
</Extension>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TerminalApp.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Terminal.TerminalApp.AppKeyBindings" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.Terminal.TerminalApp.TermApp" ThreadingModel="both" />
</InProcessServer>
</Extension>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TerminalConnection.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Terminal.TerminalConnection.EchoConnection" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.Terminal.TerminalConnection.ConhostConnection" ThreadingModel="both" />
</InProcessServer>
</Extension>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>TerminalControl.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Terminal.TerminalControl.TermControl" ThreadingModel="both" />
</InProcessServer>
</Extension>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>Microsoft.UI.Xaml.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.NavigationViewItemAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.RepeaterAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.MenuBarItemAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.RatingControlAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.ColorSpectrumAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.TreeViewItemAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.AnimatedVisualPlayerAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.MenuBarAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.ScrollerAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.TeachingTipAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.DropDownButtonAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.PersonPictureAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.ToggleSplitButtonAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.ColorPickerSliderAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.TreeViewListAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.SplitButtonAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Automation.Peers.RadioButtonsListViewItemAutomationPeer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RecyclingElementFactory" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.CommandBarFlyout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ScrollAnchorProvider" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TreeViewItemTemplateSettings" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.UniformGridLayout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.IndexPath" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RadioMenuFlyoutItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.DropDownButton" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ItemsSourceView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TreeViewList" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.VirtualizingLayoutContext" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RadioButtons" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.IconSource" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewTemplateSettings" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ElementAnimator" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.UniformGridLayoutState" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RatingControl" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SelectionModel" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ItemsRepeater" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ScrollViewer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ElementFactoryRecycleArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.FlowLayoutState" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ElementFactoryGetArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RatingItemImageInfo" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.BitmapIconSource" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.LayoutContext" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TextCommandBarFlyout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewItemSeparator" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TeachingTipTemplateSettings" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TwoPaneView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.MenuBarItemFlyout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.XamlControlsResources" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.StackLayout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewItemHeader" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RefreshVisualizer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.PathIconSource" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NonVirtualizingLayout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RatingItemFontInfo" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.PersonPicture" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TabView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SwipeControl" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.MenuBarItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.VirtualizingLayout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SymbolIconSource" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Layout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RefreshContainer" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ZoomOptions" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ParallaxView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewItemBase" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TreeViewNode" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SplitButton" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.MenuBar" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.FontIconSource" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ElementFactory" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.FlowLayout" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ScrollOptions" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TabViewItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewList" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TreeViewItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollerSnapPointBase" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.NavigationViewItemPresenter" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.RadioButtonsListViewItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollFromRequestedEventArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ColorSpectrum" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ColorPickerSlider" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.RadioButtonsListView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollerSnapPointIrregular" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollToRequestedEventArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.Scroller" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerInteractionRequestedEventArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollByRequestedEventArgs" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.CommandBarFlyoutCommandBar" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.Primitives.ScrollerSnapPointRegular" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TreeView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ColorPicker" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RecyclePool" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RevealListViewItemPresenter" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.ToggleSplitButton" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.RatingItemInfo" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.TeachingTip" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SwipeItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationViewItem" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.LayoutPanel" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NonVirtualizingLayoutContext" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.NavigationView" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.SwipeItems" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Controls.StackLayoutState" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Media.RevealBackgroundBrush" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Media.RevealBorderBrush" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Media.RevealBrush" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="Microsoft.UI.Xaml.Media.AcrylicBrush" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
</Package>

View File

@@ -0,0 +1,141 @@
<?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 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>
<!--
This manifest makes launching the exe directly via unpackaged winrt possible.
The exe can quickly be tested with `openterm` from a razzle window.
The more official way of testing however is to use the CascadiaPackage appx.
Whenever you add new cppwinrt classes, make sure to add them here.
If you need help with the syntax, the generated AppxManifest.xml should have
the classes and files all listed in it.
TODO MSFT#21300206: Switch to automatically generating these.
-->
<file name="TerminalSettings.dll" hashalg="SHA1">
<activatableClass name="Microsoft.Terminal.Settings.KeyChord" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.Terminal.Settings.TerminalSettings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="TerminalApp.dll" hashalg="SHA1">
<activatableClass name="TerminalApp.App" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="TerminalApp.AppKeyBindings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="TerminalApp.XamlmetaDataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="TerminalConnection.dll" hashalg="SHA1">
<activatableClass name="Microsoft.Terminal.TerminalConnection.ConhostConnection" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.Terminal.TerminalConnection.EchoConnection" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="TerminalControl.dll" hashalg="SHA1">
<activatableClass name="Microsoft.Terminal.TerminalControl.TermControl" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="Microsoft.UI.Xaml.dll" hashalg="SHA1">
<activatableClass name="Microsoft.UI.Xaml.Controls.IconSource" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.BitmapIconSource" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ColorPicker" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.CommandBarFlyout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.DropDownButton" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ElementAnimator" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ElementFactory" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ElementFactoryGetArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ElementFactoryRecycleArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Layout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.VirtualizingLayout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.FlowLayout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.FlowLayoutState" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.FontIconSource" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.IndexPath" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ItemsRepeater" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ItemsRepeaterScrollHost" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ItemsSourceView" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.LayoutContext" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.LayoutPanel" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.MenuBar" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.MenuBarItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.MenuBarItemFlyout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationView" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewItemBase" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewItemHeader" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewItemSeparator" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewList" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NavigationViewTemplateSettings" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NonVirtualizingLayout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.NonVirtualizingLayoutContext" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ParallaxView" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.PathIconSource" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.PersonPicture" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ColorPickerSlider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ColorSpectrum" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.CommandBarFlyoutCommandBar" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.NavigationViewItemPresenter" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.RadioButtonsListView" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.RadioButtonsListViewItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.SnapPointBase" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollSnapPointBase" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.RepeatedScrollSnapPoint" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ZoomSnapPointBase" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.RepeatedZoomSnapPoint" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerInteractionRequestedEventArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollByRequestedEventArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollFromRequestedEventArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollControllerScrollToRequestedEventArgs" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ScrollSnapPoint" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.Scroller" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.Primitives.ZoomSnapPoint" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RadioButtons" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RadioMenuFlyoutItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RatingControl" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RatingItemInfo" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RatingItemFontInfo" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RatingItemImageInfo" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RecyclePool" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RecyclingElementFactory" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RefreshContainer" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RefreshVisualizer" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.RevealListViewItemPresenter" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ScrollOptions" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ScrollViewer" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SelectionModel" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SplitButton" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.StackLayout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.StackLayoutState" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SwipeControl" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SwipeItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SwipeItems" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.SymbolIconSource" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.TabView" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.TabViewItem" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.UniformGridLayout" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.UniformGridLayoutState" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.VirtualizingLayoutContext" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.XamlControlsResources" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Controls.ZoomOptions" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Media.AcrylicBrush" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Media.RevealBrush" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Media.RevealBackgroundBrush" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.Media.RevealBorderBrush" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
<activatableClass name="Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
<file name="Microsoft.Toolkit.Win32.UI.XamlHost.dll" hashalg="SHA1">
<activatableClass name="Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1"></activatableClass>
</file>
</assembly>

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)\src\common.build.pre.props" />
<!-- ========================= Headers ======================== -->
<ItemGroup>
<ClInclude Include="precomp.h" />
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
<ItemGroup>
<ClCompile Include="JsonTests.cpp" />
<ClCompile Include="SettingsTests.cpp" />
<ClCompile Include="TabTests.cpp" />
<ClCompile Include="precomp.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
you want to use jsoncpp -->
<ClCompile Include="$(OpenConsoleDir)\dep\jsoncpp\jsoncpp.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)\src\types\lib\types.vcxproj" />
</ItemGroup>
<!-- ========================= Globals ======================== -->
<PropertyGroup>
<ProjectGuid>{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>TerminalAppUnitTests</RootNamespace>
<ProjectName>UnitTests_TerminalApp</ProjectName>
<TargetName>Terminal.App.Unit.Tests</TargetName>
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<!-- ====================== Compiler & Linker Flags ===================== -->
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\Generated Files";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
<!-- Manually disable unreachable code warning, because jconcpp has a ton of that. -->
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<GenerateManifest>true</GenerateManifest>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<ItemGroup>
<Manifest Include="TerminalApp.Unit.Tests.manifest" />
</ItemGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(OpenConsoleDir)src\common.build.dll.props" />
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\common.build.tests.props" />
<PropertyGroup>
<!-- Manually change our outdir to be in a subdirectory. We don't really want
to put our output in the bin root, because if we do, we'll copy
TerminalApp.winmd to the bin root, and then every subsequent mdmerge step
(in _any_ cppwinrt project) will automatically try to pick up
TerminalApp.winmd as a dependency (which is just wrong). This MUST be done
after importing common.build.post.props-->
<OutDir>$(OpenConsoleDir)\bin\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
<IntDir>$(OpenConsoleDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup>
<_CppWinrtBinRoot>&quot;$(OpenConsoleDir)$(Platform)\$(Configuration)\&quot;</_CppWinrtBinRoot>
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.2.190611001-prerelease\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<ItemDefinitionGroup>
<PreBuildEvent>
<!-- Manually copy the Windows Terminal manifest to our project directory,
so we only need to have one version for the entire solution. -->
<Command>
(xcopy /Y &quot;$(OpenConsoleDir)src\cascadia\WindowsTerminal\WindowsTerminal.manifest&quot; &quot;$(OpenConsoleDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest*&quot; )
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<PostBuildEvent>
<!-- Manually copy A few needed things to our outdir.
1. Our manifest, because some tests that can run unpackaged will need that
to activate winrt types.
2. Our AppManifest, for tests that _can't_ run unpackaged. Taef will use
this during execution to create a temp package to run the tests in.
3. All our dependent dlls, for any cppwinrt projects we have. We'll need
them adjacent if we hope to activate any types contained in them. This
also includes MUX manually, as the MUX targets from the nuget package
don't work on this project :/
-->
<Command>
echo OutDir=$(OutDir)
(xcopy /Y &quot;$(OpenConsoleDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.manifest&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.manifest*&quot; )
(xcopy /Y &quot;$(OpenConsoleDir)src\cascadia\ut_app\TerminalApp.Unit.Tests.AppxManifest.xml&quot; &quot;$(OutDir)\TerminalApp.Unit.Tests.AppxManifest.xml*&quot; )
(xcopy /Y $(_CppWinrtBinRoot)TerminalConnection\TerminalConnection.dll &quot;$(OutDir)\TerminalConnection.dll*&quot; )
(xcopy /Y $(_CppWinrtBinRoot)TerminalSettings\TerminalSettings.dll &quot;$(OutDir)\TerminalSettings.dll*&quot; )
(xcopy /Y $(_CppWinrtBinRoot)TerminalControl\TerminalControl.dll &quot;$(OutDir)\TerminalControl.dll*&quot; )
(xcopy /Y $(_MUXBinRoot)Microsoft.UI.Xaml.dll &quot;$(OutDir)\Microsoft.UI.Xaml.dll*&quot; )
(xcopy /Y $(_MUXBinRoot)Microsoft.UI.Xaml.pri &quot;$(OutDir)\Microsoft.UI.Xaml.pri*&quot; )
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
</Project>

View File

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

View File

@@ -3,33 +3,20 @@ Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- pch.h
- precomp.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).
Author(s):
- Carlos Zamora (cazamor) April 2019
--*/
#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
#include <unknwn.h>
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <shellscalingapi.h>
#include "../inc/LibraryIncludes.h"
// This includes support libraries from the CRT, STL, WIL, and GSL
#include "LibraryIncludes.h"
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
@@ -37,16 +24,30 @@ Abstract:
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <WexTestClass.h>
#include <json.h>
#include "consoletaeftemplates.hpp"
// 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:
// * Controls for grid
// * Media for ScaleTransform
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.ui.xaml.media.h>
// Common includes for most tests:
#include "../../inc/argb.h"
#include "../../inc/conattrs.hpp"
#include "../../types/inc/utils.hpp"
#include "../../inc/DefaultSettings.h"
#include <wil/resource.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <windows.ui.xaml.media.dxinterop.h>

View File

@@ -73,7 +73,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<AdditionalOptions>/std:c++17 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>EXTERNAL_BUILD;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -5,11 +5,11 @@
<PreprocessorDefinitions>UNIT_TESTING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.30.180808002\build\Taef.Redist.Wlk.targets" Condition="Exists('$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.30.180808002\build\Taef.Redist.Wlk.targets')" />
<Import Project="$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Taef.Redist.Wlk.targets" Condition="Exists('$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Taef.Redist.Wlk.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('$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.30.180808002\build\Taef.Redist.Wlk.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.30.180808002\build\Taef.Redist.Wlk.targets'))" />
<Error Condition="!Exists('$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Taef.Redist.Wlk.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(MSBuildThisFileDirectory)..\packages\Taef.Redist.Wlk.10.38.190610001-uapadmin\build\Taef.Redist.Wlk.targets'))" />
</Target>
</Project>

View File

@@ -64,13 +64,13 @@
</ItemDefinitionGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\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('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@@ -3,7 +3,7 @@
<Import Project="..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190417.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<!-- 17134 is RS4 -->

View File

@@ -21,6 +21,79 @@ const std::wstring_view ConsoleArguments::INHERIT_CURSOR_ARG = L"--inheritcursor
const std::wstring_view ConsoleArguments::FEATURE_ARG = L"--feature";
const std::wstring_view ConsoleArguments::FEATURE_PTY_ARG = L"pty";
std::wstring EscapeArgument(std::wstring_view ac)
{
if (ac.empty())
{
return L"\"\"";
}
bool hasSpace = false;
auto n = ac.size();
for (auto c : ac)
{
switch (c)
{
case L'"':
case L'\\':
n++;
break;
case ' ':
case '\t':
hasSpace = true;
break;
default:
break;
}
}
if (hasSpace)
{
n += 2;
}
if (n == ac.size())
{
return std::wstring{ ac };
}
std::wstring buf;
if (hasSpace)
{
buf.push_back(L'"');
}
size_t slashes = 0;
for (auto c : ac)
{
switch (c)
{
case L'\\':
slashes++;
buf.push_back(L'\\');
break;
case L'"':
{
for (; slashes > 0; slashes--)
{
buf.push_back(L'\\');
}
buf.push_back(L'\\');
buf.push_back(c);
}
break;
default:
slashes = 0;
buf.push_back(c);
break;
}
}
if (hasSpace)
{
for (; slashes > 0; slashes--)
{
buf.push_back(L'\\');
}
buf.push_back(L'"');
}
return buf;
}
ConsoleArguments::ConsoleArguments(const std::wstring& commandline,
const HANDLE hStdIn,
const HANDLE hStdOut) :
@@ -272,7 +345,7 @@ void ConsoleArguments::s_ConsumeArg(_Inout_ std::vector<std::wstring>& args, _In
size_t j = 0;
for (j = index; j < args.size(); j++)
{
_clientCommandline += args[j];
_clientCommandline += EscapeArgument(args[j]); // escape commandline
if (j + 1 < args.size())
{
_clientCommandline += L" ";

View File

@@ -16,7 +16,7 @@ TRACELOGGING_DEFINE_PROVIDER(
(0x770aa552, 0x671a, 0x5e97, 0x57, 0x9b, 0x15, 0x17, 0x09, 0xec, 0x0d, 0xbd),
TraceLoggingOptionMicrosoftTelemetry());
static bool ShouldUseConhostV2()
static bool ConhostV2ForcedInRegistry()
{
// If the registry value doesn't exist, or exists and is non-zero, we should default to using the v2 console.
// Otherwise, in the case of an explicit value of 0, we should use the legacy console.
@@ -83,9 +83,21 @@ static bool ShouldUseConhostV2()
}
}
static bool ShouldUseLegacyConhost(const bool fForceV1)
static bool ShouldUseLegacyConhost(const ConsoleArguments& args)
{
return fForceV1 || !ShouldUseConhostV2();
if (args.InConptyMode())
{
return false;
}
if (args.GetForceV1())
{
return true;
}
// Per the documentation in ConhostV2ForcedInRegistry, it checks the value
// of HKCU\Console:ForceV2. If it's *not found* or nonzero, "v2" is forced.
return !ConhostV2ForcedInRegistry();
}
[[nodiscard]] static HRESULT ActivateLegacyConhost(const HANDLE handle)
@@ -163,7 +175,7 @@ int CALLBACK wWinMain(
HRESULT hr = args.ParseCommandline();
if (SUCCEEDED(hr))
{
if (ShouldUseLegacyConhost(args.GetForceV1()))
if (ShouldUseLegacyConhost(args))
{
if (args.ShouldCreateServerHandle())
{

View File

@@ -35,12 +35,6 @@ using WEX::Logging::Log;
class AliasTests
{
BEGIN_TEST_CLASS(AliasTests)
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"conhost.exe")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincon.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"winconp.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl1.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl3.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"api-ms-win-core-console-l3-2-0.lib")
END_TEST_CLASS()
BEGIN_TEST_METHOD(TestGetConsoleAlias)

View File

@@ -14,11 +14,6 @@ class BufferTests
{
BEGIN_TEST_CLASS(BufferTests)
TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method")
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"conhost.exe")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincon.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"winconp.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl1.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl2.h")
END_TEST_CLASS()
TEST_METHOD(TestSetConsoleActiveScreenBufferInvalid);

View File

@@ -10,13 +10,6 @@
class CursorTests
{
BEGIN_TEST_CLASS(CursorTests)
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"conhost.exe")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincon.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"winconp.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincontypes.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl1.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl2.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl3.h")
END_TEST_CLASS()
TEST_METHOD_SETUP(TestSetup);

View File

@@ -17,12 +17,6 @@ using namespace WEX::Common;
class DimensionsTests
{
BEGIN_TEST_CLASS(DimensionsTests)
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"conhost.exe")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincon.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"winconp.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincontypes.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl1.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl2.h")
END_TEST_CLASS()
TEST_METHOD_SETUP(TestSetup);

View File

@@ -21,12 +21,6 @@ class FileTests
// the buffer and cursor position for each test. Launching a new OpenConsole is much quicker.
BEGIN_TEST_CLASS(FileTests)
TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method")
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"conhost.exe")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincon.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"winconp.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"wincontypes.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl1.h")
TEST_CLASS_PROPERTY(L"ArtifactUnderTest", L"conmsgl2.h")
END_TEST_CLASS();
TEST_METHOD(TestUtf8WriteFileInvalid);

Some files were not shown because too many files have changed in this diff Show More