## Summary of the Pull Request
**If you're reading this PR and haven't signed off on #8135, go there first.**
![window-management-000](https://user-images.githubusercontent.com/18356694/103932910-25199380-50e8-11eb-97e3-594a31da62d2.gif)
This provides the basic parts of the implementation of #4472. Namely:
* We add support for the `--window,-w <window-id>` argument to `wt.exe`, to allow a commandline to be given to another window.
* If `window-id` is `0`, run the given commands in _the current window_.
* If `window-id` is a negative number, run the commands in a _new_ Terminal window.
* If `window-id` is the ID of an existing window, then run the commandline in that window.
* If `window-id` is _not_ the ID of an existing window, create a new window. That window will be assigned the ID provided in the commandline. The provided subcommands will be run in that new window.
* If `window-id` is omitted, then create a new window.
## References
* Spec: #8135
* Megathread: #5000
* Project: projects/5
## PR Checklist
* [x] Closes#4472
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - **sure does**
## Detailed Description of the Pull Request / Additional comments
Note that `wt -w 1 -d c:\foo cmd.exe` does work, by causing window 1 to change
There are limitations, and there are plenty of things to work on in the future:
* [ ] We don't support names for windows yet
* [ ] We don't support window glomming by default, or a setting to configure what happens when `-w` is omitted. I thought it best to lay the groundwork first, then come back to that.
* [ ] `-w 0` currently just uses the "last activated" window, not "the current". There's more follow-up work to try and smartly find the actual window we're being called from.
* [ ] Basically anything else that's listed in projects/5.
I'm cutting this PR where it currently is, because this is already a huge PR. I believe the remaining tasks will all be easier to land, once this is in.
## Validation Steps Performed
I've been creating windows, and closing them, and running cmdlines for a while now. I'm gonna keep doing that while the PR is open, till no bugs remain.
# TODOs
* [x] There are a bunch of `GetID`, `GetPID` calls that aren't try/caught 😬
- [x] `Monarch.cpp`
- [x] `Peasant.cpp`
- [x] `WindowManager.cpp`
- [x] `AppHost.cpp`
* [x] If the monarch gets hung, then _you can't launch any Terminals_ 😨 We should handle this gracefully.
- Proposed idea: give the Monarch some time to respond to a proposal for a commandline. If there's no response in that timeframe, this window is now a _hermit_, outside of society entirely. It can't be elected Monarch. It can't receive command lines. It has no ID.
- Could we gracefully recover from such a state? maybe, probably not though.
- Same deal if a peasant hangs, it could end up hanging the monarch, right? Like if you do `wt -w 2`, and `2` is hung, then does the monarch get hung waiting on the hung peasant?
- After talking with @miniksa, **we're gonna punt this from the initial implementation**. If people legit hit this in the wild, we'll fix it then.
This PR adds a sample monarch/peasant application. This is a type of
application where a single "Monarch" can coordinate the actions of multiple
other "Peasant" processes, as described by the specs in #7240 and #8135.
This project is intended to be a standalone sample of how the architecture would
work, without involving the entirety of the Windows Terminal build. Eventually,
this architecture will be incorporated into `wt.exe` itself, to enable scenarios
like:
* Run `wt` in the current window (#4472)
* Single Instance Mode (#2227)
For an example of this sample running, see the below GIF:
![monarch-peasant-sample-001](https://user-images.githubusercontent.com/18356694/98262202-f39b1500-1f4a-11eb-9220-4af4d922339f.gif)
This sample operates largely by printing to the console, to help the reader
understand how it's working through its logic.
I'm doing this mostly so we can have a _committed_ sample of this type of application, kinda like how VtPipeTerm is a sample ConPTY application. It's a lot easier to understand (& build on) when there aren't any window shenanigans, settings loading, Island instantiation, or anything else that the whole of `WindowsTerminal.exe` needs
* [x] I work here
* [x] This is sample code, so I'm not shipping tests for it.
* [x] Go see the doc over in #8135
Adds a `Microsoft.Terminal.Remoting.dll` to our solution. This DLL will
be responsible for all the Monarch/Peasant work that's been described in
#7240 & #8135.
This PR does _not_ implement the Monarch/Peasant architecture in any
significant way. The goal of this PR is to just to establish the project
layout, and the most basic connections. This should make reviewing the
actual meat of the implementation (in a later PR) easier. It will also
give us the opportunity to include some of the basic weird things we're
doing (with `CoRegisterClass`) in the Terminal _now_, and get them
selfhosted, before building on them too much.
This PR does have windows registering the `Monarch` class with COM. When
windows are created, they'll as the Monarch if they should create a new
window or not. In this PR, the Monarch will always reply "yes, please
make a new window".
Similar to other projects in our solution, we're adding 3 projects here:
* `Microsoft.Terminal.Remoting.lib`: the actual implementation, as a
static lib.
* `Microsoft.Terminal.Remoting.dll`: The implementation linked as a DLL,
for use in `WindowsTerminal.exe`.
* `Remoting.UnitTests.dll`: A unit test dll that links with the static
lib.
There are plenty of TODOs scattered about the code. Clearly, most of
this isn't implemented yet, but I do have more WIP branches. I'm using
[`projects/5`](https://github.com/microsoft/terminal/projects/5) as my
notation for TODOs that are too small for an issue, but are part of the
whole Process Model 2.0 work.
## References
* #5000 - this is the process model megathread
* #7240 - The process model 2.0 spec.
* #8135 - the window management spec. (please review me, I have 0/3
signoffs even after the discussion we had 😢)
* #8171 - the Monarch/peasant sample. (please review me, I have 1/2)
## PR Checklist
* [x] Closes nothing, this is just infrastructure
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
This commit introduces the terminal settings editor (to wit: the
Settings UI) as a standalone project. This project, and this commit, is
the result of two and a half months of work.
TSE started as a hackathon project in the Microsoft 2020 Hackathon, and
from there it's grown to be a bona-fide graphical settings editor.
There is a lot of xaml data binding in here, a number of views and a
number of view models, and a bunch of paradigms that we've been
reviewing and testing out and designing and refining.
Specified in #6720, #8269
Follow-up work in #6800Closes#1564Closes#8048 (PR)
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Kayla Cinnamon <cinnamon@microsoft.com>
Co-authored-by: Alberto Medina Gutierrez <almedina@microsoft.com>
Co-authored-by: John Grandle <jograndl@microsoft.com>
Co-authored-by: xerootg <xerootg@users.noreply.github.com>
Co-authored-by: Scott <sarmiger1@gmail.com>
Co-authored-by: Vineeth Thomas Alex <vineeththomasalex@gmail.com>
Co-authored-by: Leon Liang <lelian@microsoft.com>
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Signed-off-by: Dustin L. Howett <duhowett@microsoft.com>
There were some minor annoyances with the WPF projects.
1. WpfTerminalTestNetCore was in an unnecessary same-named subdirectory
2. The build started throwing deprecation warnings because `netcoreapp3.0` is not LTS and is going away.
Introduces a new TerminalSettingsModel (TSM) project. This project is
responsible for (de)serializing and exposing Windows Terminal's settings
as WinRT objects.
## References
#885: TSM epic
#1564: Settings UI is dependent on this for data binding and settings access
#6904: TSM Spec
In the process of ripping out TSM from TerminalApp, a few other changes
were made to make this possible:
1. AppLogic's `ApplicationDisplayName` and `ApplicationVersion` was
moved to `CascadiaSettings`
- These are defined as static functions. They also no longer check if
`AppLogic::Current()` is nullptr.
2. `enum LaunchMode` was moved from TerminalApp to TSM
3. `AzureConnectionType` and `TelnetConnectionType` were moved from the
profile generators to their respective TerminalConnections
4. CascadiaSettings' `SettingsPath` and `DefaultSettingsPath` are
exposed as `hstring` instead of `std::filesystem::path`
5. `Command::ExpandCommands()` was exposed via the IDL
- This required some of the warnings to be saved to an `IVector`
instead of `std::vector`, among some other small changes.
6. The localization resources had to be split into two halves.
- Resource file linked in init.cpp. Verified at runtime thanks to the
StaticResourceLoader.
7. Added constructors to some `ActionArgs`
8. Utils.h/cpp were moved to `cascadia/inc`. `JsonKey()` was moved to
`JsonUtils`. Both TermApp and TSM need access to Utils.h/cpp.
A large amount of work includes moving to the new namespace
(`TerminalApp` --> `Microsoft::Terminal::Settings::Model`).
Fixing the tests had its own complications. Testing required us to split
up TSM into a DLL and LIB, similar to TermApp. Discussion on creating a
non-local test variant can be found in #7743.
Closes#885
The easiest fix was actually just moving all the source files from
`TerminalApp` to `TerminalApp/lib`, where the appropriate `pch.h`
actually resides.
Closes#6866
## Summary of the Pull Request
Move `ICoreSettings` and `IControlSettings` from the TerminalSettings project to the TerminalCore and TerminalControl projects respectively. Also entirely removes the TerminalSettings project.
The purpose of these interfaces is unchanged. `ICoreSettings` is used to instantiate a terminal. `IControlSettings` (which requires an `ICoreSettings`) is used to instantiate a UWP terminal control.
## References
Closes#7140
Related Epic: #885
Related Spec: #6904
## PR Checklist
* [X] Closes#7140
* [X] CLA signed
* [X] Tests ~added~/passed (no additional tests necessary)
* [X] ~Documentation updated~
* [X] ~Schema updated~
## Detailed Description of the Pull Request / Additional comments
A lot of the work here was having to deal with winmd files across all of these projects. The TerminalCore project now outputs a Microsoft.Terminal.TerminalControl.winmd. Some magic happens in TerminalControl.vcxproj to get this to work properly.
## Validation Steps Performed
Deployed Windows Terminal and opened a few new tabs.
Due to a shell limitation, Ctrl+Shift+Enter will not launch Windows
Terminal as Administrator. This is caused by the app execution alias and
the actual targeted executable not having the same name.
In addition, PowerShell has an issue detecting app execution aliases as
GUI/TUI applications. When you run wt from PowerShell, the shell will
wait for WT to exit before returning to the prompt. Having a shim that
immediately re-executes WindowsTerminal and then returns handily knocks
this issue out (as the process that PS was waiting for exits
immediately.)
This could cause a regression for anybody who tries to capture the PID
of wt.exe. Our process tree is not an API, and we have offered no
consistency guarantee on it.
VALIDATION
----------
Tested manual launch in a number of different scenarios:
* [x] start menu "wtd"
* [x] start menu tile
* [x] powertoys run
* [x] powertoys run ctrl+shift (admin)
* [x] powershell inbox, "core"
* [x] cmd
* [x] run dialog
* [x] run dialog ctrl+shift (admin)
* [x] run from a lnk with window mode=maximized
Fixes#4645 (PowerShell waits for wt)
Fixes#6625 (Can't launch as admin using C-S-enter)
This commit introduces a new project that lets you F5 a working instance
of the Wpf Terminal Control.
To make the experience as seamless as possible, I've introduced another
solution platform called "DotNet_x64Test". It is set to build the WPF
projects for "Any CPU" and every project that PublicTerminalCore
requires (including itself) for "x64". This is the only way to ensure
that when you press F5, all of the native and managed dependencies get
updated.
It's all quite cool when it works.
We received a request from our localization team to switch from
printf-style format strings (%s, %u) to format strings with positional
argument support. I've been hoping for a long time to take a dependency
on C++20's std::format, but we're just not somewhere we can do that.
Enter fmt. fmt is _exactly_ the library we need.
Minor comparison:
std::wstring_view world = /* ... */;
auto str{ wil::str_printf<std::wstring>(L"hello %.*s",
gsl::narrow_cast<size_t>(world.size()),
world.data()) };
---
auto str{ fmt::format(L"hello {0}", world) };
If you really want to use the print specifiers:
auto str{ fmt::printf(L"hello %s", world) };
It's got optional compile-time checking for format strings and is
MIT-licensed. Eventually, we should be able to replace fmt:: with std::
and end up pretty much where we left off.
What more could you ask for?
## Summary of the Pull Request
Adjusts `DrawGlyphRun` method inside DirectX renderer to restrict text
to be clipped within the boundaries of the row.
## PR Checklist
* [x] Closes#1703
* [x] I work here.
* [x] No tests.
* [x] No docs.
* [x] I am core contributor.
## Detailed Description of the Pull Request / Additional comments
For whatever reason, some of these shade glyphs near U+2591 tend to
extend way above the height of where we expect they should. This didn't
look like a problem in conhost because it clipped every draw inside the
bounds. This therefore applies the same clip logic as people don't
really expect text to pour out of the box.
It could, theoretically, get us into trouble later should someone
attempt zalgo text. But doing zalgo text is more of a silliness that
varies in behavior across rendering platforms anyway.
## Validation Steps Performed
- Ran the old conhost GDI renderer and observed
- Ran the new Terminal DX renderer and observed
- Made the code change
- Observed that the height and approximate display characteristics of
the U+2591 shade and neighboring characters now matches with the conhost
GDI style to stay within its lane.
## Summary of the Pull Request
- Height adjustment of a glyph is now restricted to itself in the DX
renderer instead of applying to the entire run
- ConPTY compensates for drawing the right half of a fullwidth
character. The entire render base has this behavior restored now as
well.
## PR Checklist
* [x] Closes#2191
* [x] I work here
* [x] Tests added/passed
* [x] No doc
* [x] Am core contributor.
## Detailed Description of the Pull Request / Additional comments
Two issues:
1. On the DirectX renderer side, when confronted with shrinking a glyph,
the correction code would apply the shrunken size to the entire run, not
just the potentially individual glyph that needed to be reduced in size.
Unfortunately while adjusting the horizontal X width can be done for
each glyph in a run, the vertical Y height has to be adjusted for an
entire run. So the solution here was to split the individual glyph
needing shrinking out of the run into its own run so it can be shrunk.
2. On the ConPTY side, there was a long standing TODO that was never
completed to deal with a request to draw only the right half of a
two-column character. This meant that when encountering a request for
the right half only, we would transmit the entire full character to be
drawn, left and right halves, struck over the right half position. Now
we correct the cursor back a position (if space) and draw it out so the
right half is struck over where we believe the right half should be (and
the left half is updated as well as a consequence, which should be OK.)
The reason this happens right now is because despite VIM only updating
two cells in the buffer, the differential drawing calculation in the
ConPTY is very simplistic and intersects only rectangles. This means
from the top left most character drawn down to the row/col cursor count
indicator in vim's modeline are redrawn with each character typed. This
catches the line below the edited line in the typing and refreshes it.
But incorrectly.
We need to address making ConPTY smarter about what it draws
incrementally as it's clearly way too chatty. But I plan to do that with
some of the structures I will be creating to solve #778.
## Validation Steps Performed
- Ran the scenario listed in #2191 in vim in the Terminal
- Added unit tests similar to examples given around glyph/text mapping
in runs from Microsoft community page
This commit introduces a small console-subsystem application whose sole
job is to consume TerminalConnection.dll and hook it up to something
other than Terminal. It is 99% of the way to a generic solution.
I've introduced a stopgap in TerminalPage that makes sure we launch
TerminalAzBridge using ConptyConnection instead of AzureConnection.
As a bonus, this commit includes a class whose sole job it is to make
reading VT input off a console handle not terrible. It returns you a
string and dispatches window size change callbacks.
Fixes#2267.
Fixes#4589.
Related to #2266 (since pwsh needs better VT).
## Summary of the Pull Request
This will allow us to run the ConPTY tests in CI.
## PR Checklist
* [x] Closes MSFT:24265197
* [X] I've discussed this with core contributors already.
## Validation Steps Performed
I've run the tests.
Please note: this code is unchanged (apart from `wil::ScopeExit` -> `wil::scope_exit`) from Windows. Now is not the time to comment on their perfectness.
Moves the tests from using the `vstest.console.exe` route to just using `te.exe`.
PROs:
- `te.exe` is significantly faster for running tests because the TAEF/VSTest adapter isn't great.
- Running through `te.exe` is closer to what our developers are doing on their dev boxes
- `te.exe` is how they run in the Windows gates.
- `te.exe` doesn't seem to have the sporadic `0x6` error code thrown during the tests where somehow the console handles get lost
- `te.exe` doesn't seem to repro the other intermittent issues that we have been having that are inscrutable.
- Fewer processes in the tree (te is running anyway under `vstest.console.exe`, just indirected a lot
- The log outputs scroll live with all our logging messages instead of suppressing everything until there's a failure
- The log output is actually in the order things are happening versus vstest.
CONs:
- No more code coverage.
- No more test records in the ADO build/test panel.
- Tests really won't work inside Visual Studio at all.
- The log files are really big now
- Testing is not a test task anymore, just another script.
Refuting each CON:
- We didn't read the code coverage numbers
- We didn't look at the ADO test panel results or build-over-build velocities
- Tests didn't really work inside Visual Studio anyway unless you did the right incantations under the full moon.
- We could tone down the logging if we wanted at either the te.exe execution time (with a switch) or by declaring properties in the tests/classes/modules that are very verbose to not log unless it fails.
- I don't think anyone cares how they get run as long as they do.
## Summary of the Pull Request
In #4213 I added a dependency to the `UnitTests_TerminalCore` project on basically all of conhost. This _worked on my machine_, but it's consistently not working on other machines. This should fix those issues.
## References
## PR Checklist
* [x] Closes#4285
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
Made a fresh clone and built it.
## Summary of the Pull Request
New year, new unittests.
This PR introduces a new project, `TestHostApp`. This project is largely taken from the TAEF samples, and allows us to easily construct a helper executable and `resources.pri` for running TerminalApp unittests.
## References
## PR Checklist
* [x] Closes#3986
* [x] I work here
* [x] is Tests
* [n/a] Requires documentation to be updated
* [x] **Waiting for an updated version of TAEF to be available**
## Detailed Description of the Pull Request / Additional comments
Unittesting for the TerminalApp project has been a horrifying process to try getting everything pieced together just right. Dependencies need to get added to manifests, binplaced correctly, and XAML resources need to get compiled together as well. In addition, using a MUX `Application` (as opposed to the Windows.UI.Xaml `Application`) has led to additional problems.
This was always a horrifying house of cards for us. Turns out, the reason this was so horrible is that the test infrastructure for doing what we're doing _literally didn't exist_ when I started doing all that work last year.
So, with help from the TAEF team, I was able to get rid of our entire house of cards, and use a much simpler project to build and run the tests.
Unfortunately, the latest TAEF release has a minor bug in it's build rules, and only publishes the x86 version of a dll we need from them. But, the rest of this PR works for x86, and I'll bump this when that updated version is available. We should be able to review this even in the state it's in.
## Validation Steps Performed
ran the tests yo
## Summary of the Pull Request
Introduces a type that is basically an array (stack allocated, fixed size) that reports size based on how many elements are actually filled (from the front), iterates only the filled ones, and has some basic vector push/pop semantics.
## PR Checklist
* [x] I work here
* [x] I work here
* [x] I work here
* [ ] I'd love to roll this out to SomeViewports.... maybe in this commit or a follow on one.
* [ ] We need a TIL tests library and I should test this there.
## Detailed Description of the Pull Request / Additional comments
The original gist of this was used for `SomeViewports` which was a struct to hold between 0 and 4 viewports, based on how many were left after subtraction (since rectangle subtraction functions in Windows code simply fail for resultants that yield >=2 rectangle regions.)
I figured now that we're TIL-ifying useful common utility things that this would be best suited to a template because I'm certain there are other circumstances where we would like to iterate a partially filled array and want it to not auto-resize-up like a vector would.
## Validation Steps Performed
* [ ] TIL tests added
## Summary of the Pull Request
- Enables auditing of some Terminal libraries (Connection, Core, Settings)
- Also audit WinConPTY.LIB since Connection depends on it
## PR Checklist
* [x] Rolls audit out to more things
* [x] I work here
* [x] Tests should still pass
* [x] Am core contributor
## Detailed Description of the Pull Request / Additional comments
This is turning on the auditing of these projects (as enabled by the heavier lifting in the other refactor) and then cleaning up the remaining warnings.
## Validation Steps Performed
- [x] Built it
- [x] Ran the tests
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
- Enables auditing of Virtual Terminal libraries (input, adapter, parser)
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Rolls audit out to more things
* [x] I work here
* [x] Tests should still pass
* [x] Am core contributor
* [x] Closes#3957
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
This is turning on the auditing of these projects (as enabled by the heavier lifting in the other refactor) and then cleaning up the remaining warnings.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- [x] Built it
- [x] Ran the tests
We unintentionally broke the build in #2930. If you're building the entire solution,
then you won't have any problems, because the `UiaRenderer` project will get built
before the `TerminalControl`. However, if you're like me and you only really build the
solution one project at a time, you'll find that building `TerminalControl` won't
build `UiaRenderer` automagically.
This fixes that.
s/o to @Rrogntudju for catching this
## Summary of the Pull Request
Turns on Audit for WinRTUtils, fixes audit failures.
## PR Checklist
* [x] I work here
* [x] Still builds
* [x] Am core contributor.
## Validation Steps Performed
Built it.
This PR creates a Universal entrypoint for the Windows Terminal solution
in search of our goals to run everywhere, on all Windows platforms.
The Universal entrypoint is relatively straightforward and mostly just
invokes the App without any of the other islands and win32 boilerplate
required for the centennial route. The Universal project is also its own
packaging project all in one and will emit a relevant APPX.
A few things were required to make this work correctly:
* Vcxitems reuse of resources (and link instructions on all of them
for proper pkg layout)
* Move all Terminal project CRT usages to the app ones (and ensure
forwarders are only Nugetted to the Centennial package to not pollute
the Universal one)
* Fix/delay dependencies in `TerminalApp` that are not available in
the core platform (or don't have an appropriate existing platform
forwarder... do a loader snaps check)
* vcpkg needs updating for the Azure connection parser
* font fallbacks because Consolas isn't necessarily there
* fallbacks because there are environments without a window handle
Some of those happened in other small PRs in the past week or two. They
were relevant to this.
Note, this isn't *useful* as such yet. You can run the Terminal in this
context and even get some of the shells to work. But they don't do a
whole lot yet. Scoping which shells appear in the profiles list and only
offering those that contextually make sense is future work.
* Break everything out of App except the base initialization for XAML. AppLogic is the new home.
* deduplicate logics by always using the app one (since it has to be there to support universal launch).
* apparently that was too many cross-boundary calls and we can cache it because winrt objects are magic.
* Put UWP project into solution.
* tabs in titlebar needs disabling from uwp context as the non-client is way different. This adds a method to signal that to logic and apply the setting override.
* Change to use App CRT in preparation for universal.
* Try to make project build again by setting winconpty to static lib so it'll use the CRT inside TerminalConnection (or its other consumers) instead of linking its own.
* Remove test for conpty dll, it's a lib now. Add additional commentary on how CRT linking works for future reference. I'm sure this will come up again.
* This fixes the build error.
* use the _apiset variant until proven otherwise to match the existing one.
* Merge branch 'master' into dev/miniksa/uwp3
* recorrect spacing in cppwinrt.build.pre.props
* Add multiple additional fonts to fallback to. Also, guard for invalid window handle on title update.
* Remove ARMs from solution.
* Share items resources between centennial and universal project.
* cleanup resources and split manifest for dev/release builds.
* Rev entire solution to latest Toolkit (6.0.0 stable release).
* shorten the items file using include patterns
* cleanup this filters file a bit.
* Fix C26445 by using string_view as value, not ref. Don't build Universal in Audit because we're not auditing app yet.
* some PR feedback. document losing the pointer. get rid of 16.3.9 workarounds. improve consistency of variable decl in applogic.h
* Make dev phone product ID not match prod phone ID. Fix universal package identity to match proposed license information.
* Make ConPTY build as both LIB and DLL.
* Update TerminalConnection reference to LIB version (because Terminal builds both UWP and Centennial, requiring different CRTs each).
* DLL is now available (and against desktop CRT) to be PInvokable from C# for WPF terminal.
Note, DLL MUST BUILD PRECOMP to get the magic pragma linking information to the Desktop CRT.
* don't audit PTY lib. I can't do safe things because the safe things we use don't fit back inside kernelbase.dll.
Closes#3563.
This commit cleans up and deduplicates all of the common build
preamble/postamble across exe, dll, lib and c++/winrt projects.
The following specific changes have been made:
* All projects now define their ConfigurationType
* All projects now set all their properties *before* including a common
build file (or any other build files)
* cppwinrt.pre and cppwinrt.post now delegate most of their
configuration to common.pre and common.post
* (becuase of the above,) all build options are conserved between
console and c++/winrt components, including specific warnings and
preprocessor definitions.
* More properties that are configurable per-project are now
conditioned so the common props don't override them.
* The exe, dll, exe.or.dll, and lib postincludes have been merged into
pre or post and switched based on condition as required
* Shared items (-shared, -common) are now explicitly vcxitems instead of
vcxproj files.
* The link line is now manipulated after Microsoft.Cpp sets it, so the
libraries we specify "win". All console things link first against
onecore_apiset.lib.
* Fix all compilation errors caused by build unification
* Move CascadiaPackage's resources into a separate item file
Fixes#922.
This commit introduces a C++/WinRT utility library and moves
ScopedResourceLoader into it. I decided to get uppity and introduce
something I like to call "checked resources." The idea is that every
resource reference from a library is knowable at compile time, and we
should be able to statically ensure that all resources exist.
This is a system that lets us immediately failfast (on launch) when a
library makes a static reference to a resource that doesn't exist at
runtime.
It exposes two new (preprocessor) APIs:
* `RS_(wchar_t)`: loads a localizable string resource by name.
* `USES_RESOURCE(wchar_t)`: marks a resource key as used, but is intended
for loading images or passing static resource keys as parameters to
functions that will look them up later.
Resource checking relies on diligent use of `USES_RESOURCE()` and `RS_()`
(which uses `USES_RESOURCE`), but can make sure we don't ship something
that'll blow up at runtime.
It works like this:
**IN DEBUG MODE**
- All resource names referenced through `USES_RESOURCE()` are emitted
alongside their referencing filenames and line numbers into a static
section of the binary.
That section is named `.util$res$m`.
- We emit two sentinel values into two different sections, `.util$res$a`
and `.util$res$z`.
- The linker sorts all sections alphabetically before crushing them
together into the final binary.
- When we first construct a library's scoped resource loader, we
iterate over every resource reference between `$a` and `$z` and check
residency.
**IN RELEASE MODE**
- All checked resource code is compiled out.
Fixes#2146.
Macros are the only way to do something this cool, incidentally.
## Validation Steps Performed
Made references to a bunch of bad resources, tried to break it a lot.
It looks like this when it fails:
### App.cpp
```
36 static const std::array<std::wstring_view, 2> settingsLoadErrorsLabels {
37 USES_RESOURCE(L"NoProfilesText"),
38 USES_RESOURCE(L"AllProfilesHiddenText_HA_JUST_KIDDING")
39 };
```
```
WinRTUtils\LibraryResources.cpp(68)\TerminalApp.dll:
FailFast(1) tid(1034) 8000FFFF Catastrophic failure
Msg:[Resource AllProfilesHiddenText_HA_JUST_KIDDING not found in
scope TerminalApp/Resources (App.cpp:38)] [EnsureAllResourcesArePresent]
```
The WAP packaging project in VS <= 16.3.7 produces a couple global
properties as part of its normal operation that cause MSBuild to flag
our projects as out-of-date and requiring a rebuild. By forcing those
properties to match the WAP values, we can get consistent builds.
One of those properties, however, is "GenerateAppxPackageOnBuild", and
WAP sets it to *false*. When we set that, of course, we don't get an
MSIX out of our build pipeline. Therefore, we have to break our build
into two phases -- build, then package.
This required us to change our approach to PCH deletion. A project
without a PCH is *also* considered out-of-date. Now, we keep all PCH
files but truncate them to 0 bytes.
TerminalApp, however, is re-linked during packaging because the Xaml
compiler emits a new generated C++ file on every build. We have to keep
those PCHs around.
* Remove WpfTerminalControl AnyCPU from Arch-specific builds
This removes another source of build nondeterminism: that WpfTerminalControl was propagating TargetFramework into architecture-specific C++ builds. Its "Any CPU" platform has been removed from architecture builds at the solution level.
This also cleans up some new projects that were added and build for "Any
CPU".
As a part of setting up UIA Events, we need to be able to identify WHEN to notify the client. We'll be adopting the RendererEngine model that the VTRenderer and DxRenderer follow to identify when something on the screen is changing and what to alert the automation clients about.
This PR just introduces the UiaRenderer. There's a lot of E_NOTIMPLs and S_FALSEs and a few comments throughout as to my thoughts. This'll make diffing future PRs easier and can make this process more iterative. The code does run with the PR so I plan on merging this into master as normal.
This adds the WPF control to our project, courtesy of the Visual Studio team.
It re-hosts the Terminal Control components inside a reusable WPF adapter so it can be composed onto C# type surfaces like Visual Studio requires.
This pull request introduces a copy of the code from kernel32.dll that
implements CreatePseudoConsole, ClosePseudoConsole and
ResizePseudoConsole. Apart from some light modifications to fit into the
infrastructure in this project and support launching OpenConsole.exe, it
is intended to be 1:1 with the code that ships in Windows.
Any guideline violations in this code are likely intentional. Since this
was built into kernel32, it uses the STL only _very sparingly._
Consumers of this library must make sure that conpty.lib lives earlier
in the link line than onecoreuap_apiset, onecoreuap, onecore_apiset,
onecore or kernel32.
Refs #1130.
In #1164 we learned that our CI doesn't support WinRT testing. This made us all sad. Since that merged, we haven't really added any TerminalApp tests, because it's a little too hard. You'd have to uncomment the entire file, and if the list of types changed you'd have to manually update the sxs manifest and appxmanifest.
Since that was all insane, I created a new Terminal App unittesting project without those problems.
1. The project is not named *Unit*Test*, so the CI won't run it, but it will run locally.
2. The project will auto-generate its SxS manifest, using the work from #1987.
3. We'll use the SxS manifest from step 2 to generate an AppxManifest for running packaged tests.
* This is the start of me trying to enable local unittesting again
* We've got a new unittests project that isn't named *unit*test*
* We're manually generating the SxS manifest for it. B/C we need to use it at runtime, we need to manually combine it into one manifest file
* the runas:UAP thing still doesn't work. We'll investigate.
* This shockingly works
but I'm still stuck with:
```
Summary of Errors Outside of Tests:
Error: TAEF: [HRESULT: 0x80270254] Failed to create the test host process for
out of process test execution. (The
IApplicationActivationManager::ActivateApplication call failed while using a
default host. TAEF's ETW logs which are gathered with the /enableEtwLogging
switch should contain events from relevant providers that may help to diagnose
the failure.)
```
* Cleaning this all up for review.
Frankly just pushing to see if it'll work in CI
* Couple things I noticed in the diff from master
* Apply @dhowett-msft's suggestions from code review
* Attempt to remove all test and utility projects from audit mode (and turn it back on) to see if that keeps it within the disk space boundaries.
* drop x86 and arm configs for the test projects too.
* 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
* Use a region to cut off the dragable region
* Use proper measurements for the draggable area
* Working better, paint works most of the time
* Fix a bug where paint is incomplete when double clicking the dragbar
* Remove old fork on XamlApplication
* Upgrade to XamlApp preview6.2
* Add Microsoft.VCRTForwarders to make it easy to dogfood
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
Co-Authored-By: Mike Griese <migrie@microsoft.com>
Visual Studio defaults the startup project to the first project listed in the solution. Set the default to CascadiaPackage, which launches the packaged terminal. This required moving both its solution folder and the project itself to the top of the solution.
The other moves in the file is "VS" fixing the ordering based on the move. This prevents the solution from being automatically changed by VS when other folks open it.
The OutputStateMachine needs to collect "Intermediate" characters to be able to call [`Designate G0 Character Set`](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Controls-beginning-with-ESC) (as well as other sequences we don't yet support).
However, the InputStateMachine used by conpty to process input should _not_ collect these characters. The input engine uses `\x1b` as an indicator that a key was pressed with `Alt`. For keys like `/`, we want to dispatch the key immediately, instead of collecting it and leaving us in the Escape state.
This commit switches the GUIDs for default profiles from being randomly generated to being version 5 UUIDs. More info in #870.
## PR Checklist
* [x] Closes#870
* [x] CLA signed
* [x] Tests added/passed
* [x] Requires documentation to be updated (#883)
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
This commit has a number of changes that seem ancillary, but they're general goodness. Let me explain:
* I've added a whole new Types test library with only two tests in
* Since UUIDv5 generation requires SHA1, we needed to take a dependency on bcrypt
* I honestly don't think we should have to link bcrypt in conhost, but LTO should take care of that
* I considered adding a new Terminal-specific Utils/Types library, but that seemed like a waste
* The best way to link bcrypt turned out to be in line with a discussion @miniksa and I had, where we decided we both love APISets and think that the console should link against them exclusively... so I've added `onecore_apiset.lib` to the front of the link line, where it will deflect the linker away from most of the other libs automagically.
```
StartGroup: UuidTests::TestV5UuidU8String
Verify: AreEqual(uuidExpected, uuidActual)
EndGroup: UuidTests::TestV5UuidU8String [Passed]
StartGroup: UuidTests::TestV5UuidU16String
Verify: AreEqual(uuidExpected, uuidActual)
EndGroup: UuidTests::TestV5UuidU16String [Passed]
```