When user resizes window, snap the size to align with the character grid
(like e.g. putty, mintty and most unix terminals). Properly resolves
arbitrary pane configuration (even with different font sizes and
padding) trying to align each pane as close as possible.
It also fixes terminal minimum size enforcement which was not quite well
handled, especially with multiple panes.
This PR does not however try to keep the terminals aligned at other user
actions (e.g. font change or pane split). That is to be tracked by some
other activity.
Snapping is resolved in the pane tree, recursively, so it (hopefully)
works for any possible layout.
Along the way I had to clean up some things as so to make the resulting
code not so cumbersome:
1. Pane.cpp: Replaced _firstPercent and _secondPercent with single
_desiredSplitPosition to reduce invariants - these had to be kept in
sync so their sum always gives 1 (and were not really a percent). The
desired part refers to fact that since panes are aligned, there is
usually some deviation from that ratio.
2. Pane.cpp: Fixed _GetMinSize() - it was improperly accounting for
split direction
3. TerminalControl: Made dedicated member for padding instead of
reading it from a control itself. This is because the winrt property
functions turned out to be slow and this algorithm needs to access it
many times. I also cached scrollbar width for the same reason.
4. AppHost: Moved window to client size resolution to virtual method,
where IslandWindow and NonClientIslandWindow have their own
implementations (as opposite to pointer casting).
One problem with current implementation is I had to make a long call
chain from the window that requests snapping to the (root) pane that
implements it: IslandWindow -> AppHost's callback -> App ->
TerminalPage -> Tab -> Pane. I don't know if this can be done better.
## Validation Steps Performed
Spam split pane buttons, randomly change font sizes with ctrl+mouse
wheel and drag the window back and forth.
Closes#2834Closes#2277
## Summary of the Pull Request
This latest MUX prerelease fixes the issue where the tab row wouldn't expand to fill the width of the window after shrinking the window size.
## PR Checklist
* [x] Closes#3300
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
Thanks again @teaP for help fixing this
## Validation Steps Performed
Launched the terminal, played with it a bit
For our Universal terminal for development purposes, we will use telnet to escape the universal application container and empower developers to debug/diagnose issues with their own machine on loopback to the already-elevated telnet context.
## Summary of the Pull Request
Updates MUX to the latest pre-release version. This prerelease has a fix for a certain `E_LAYOUTCYCLE` bug in the TabView that was causing an untold number of crashes for us.
Thanks again @teaP!
## PR Checklist
* [x] Closes#3303
* [x] Closes#2277
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Summary of the Pull Request
Moves all the code responsible for dispatching an `ActionAndArgs` to it's own class, `ShortcutActionDispatch`. Now, the `AppKeyBindings` just uses the single instance of a `ShortcutActionDispatch` that the `TerminalPage` owns to dispatch events, without the need to re-attach the event handlers every time we reload the settings.
## References
This is something I originally did as a part of #2046.
I need this now for #607.
It's also a part of work for #3475
## PR Checklist
* [x] This is a bullet point within #3475
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
With this change, we'll be able to have other things dispatch `ShortcutAction`s easily, by constructing an `ActionAndArgs` and just passing it straight to the `ShortcutActionDispatch`.
## Validation Steps Performed
Ran the Terminal, tried out some keybindings, namely <kbd>Ctrl+c</kbd> for copy when there is a selection, or send `^C` when there isn't. That still works.
Reloading settings also still works.
-----------------------------------------------
* Move action handling to it's own class separate from AKB. This is the first checkbox in #3475
(cherry picked from commit 696726b571d3d1fdf1d59844c76e182fc72cb2ea)
* clean up doc comments
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.
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes#1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
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]
```
Due to a platform issue, elevated application packages occasionally fail
to find all of their dependencies. The real fix for this is going to
take a lot of time and probably a new build of Windows.
The fix we have here switches us to a non-"release" build of
Microsoft.UI.Xaml. The critical thing about their non-release builds is
that they prefer to embed their DLLs into the hosting package instead of
expressing a platform dependency.
This build of Microsoft.UI.Xaml was produced from the same commit as
the original and official build; the only difference is that it will
embed into our package.
Fixes#3275.
* We had to move to the final API:
* Items -> TabItems
* Items.VectorChanged -> TabItemsChanged
* TabClose -> TabCloseRequested
* TabViewItem.Icon -> TabViewItem.IconSource
* TabRowControl has been converted to a ContentPresenter, which
simplifies its logic a little bit.
* TerminalPage now differentiates MUX and WUX a little better
* Because of the change from Icon to IconSource in TabViewItem,
Utils::GetColoredIcon needed to be augmented to support MUX IconSources.
It was still necessary to use for WUX, so it's been templatized.
* I moved us from WUX SplitButton to MUX SplitButton and brought the
style in line with the one typically provided by TabView.
* Some of our local controls have had their backgrounds removed so
they're more amenable to being placed on other surfaces.
* I'm suppressing the TabView's padding.
* I removed a number of apparently dead methods from App.
* I've simplified the dragbar's sizing logic and eventing.
* The winmd harvester needed to be taught to not try to copy winmds for
framework packages.
* We now only initialize the terminal once we know the size
Closes#1896.
Closes#444.
Closes#857.
Closes#771.
Closes#760.
_**This PR targets the #2515 PR**_. It does that for the sake of diffing. When this PR and #2515 are both ready, I'll merge #2515 first, then change the target of this branch, and merge this one.
<!-- 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
This PR adds support for "dynamic profiles", in accordance with the [Cascading Settings Spec](https://github.com/microsoft/terminal/blob/master/doc/cascadia/Cascading-Default-Settings.md#dynamic-profiles). Currently, we have three types of default profiles that fit the category of dynamic profile generators. These are profiles that we want to create on behalf of the user, but require runtime information to be able to create correctly. Because they require runtime information, we can't ship a static version of these profiles as a part of `defaults.json`. These three profile generators are:
* The Powershell Core generator
* The WSL Distro generator
* The Azure Cloud Shell generator
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#754
* [x] I work here
* [x] look at all these **Tests**
* [x] Requires documentation to be updated - This is done as part of the parent PR
<!-- 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
We want to be able to enable the user to edit dynamic profiles that are generated from DPGs. When dynamic profiles are added, we'll add entries for them to the user's `profiles.json`. We do this _without re-serializing_ the settings. Instead, we insert a partial serialization for the profile into the user's settings.
### Remaining TODOs:
* Make sure that dynamic profiles appear in the right place in the order of profiles -> #2722
* [x] don't serialize the `colorTable` key for dynamic profiles.
* [x] re-parse the user settings string if we've changed it.
* Handle changing the default profile to pwsh if it exists on first launch, or file a follow-up issue -> #2721
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
<hr>
* Create profiles by layering them
* Update test to layer multiple times on the same profile
* Add support for layering an array of profiles, but break a couple tests
* Add a defaults.json to the package
* Layer colorschemes
* Moves tests into individual classes
* adds support for layering a colorscheme on top of another
* Layer an array of color schemes
* oh no, this was missed with #2481
must have committed without staging this change, uh oh. Not like those tests actually work so nbd
* Layer keybindings
* Read settings from defaults.json + profiles.json, layer appropriately
This is like 80% of #754. Needs tests.
* Add tests for keybindings
* add support to unbind a key with `null` or `"unbound"` or `"garbage"`
* Layer or clear optional properties
* Add a helper to get an optional variable for a bunch of different types
In the end, I think we need to ask _was this worth it_
* Do this with the stretch mode too
* Add back in the GUID check for profiles
* Add some tests for global settings layering
* M A D W I T H P O W E R
Add a MsBuild target to auto-generate a header with the defaults.json as a
string in the file. That way, we can _always_ load the defaults. Literally impossible to not.
* When the user's profile.json doesn't exist, create it from a template
* Re-order profiles to match the order set in the user's profiles.json
* Add tests for re-ordering profiles to match user ordering
* Add support for hiding profiles using `"hidden": true`
* Use the hardcoded defaults.json for the exception->"use defaults" case
* Somehow I messed up the git submodules?
* woo documentation
* Fix a Terminal.App.Unit.Tests failure
* signed/unsigned is hard
* Use Alt+Settings button to open the default settings
* Missed a signed/unsigned
* Start dynamically creating profiles
* Give the inbox generators a namespace
and generally hack this a lot less
* Some very preliminary PR feedback
* More PR feedback
Use the wil helper for the exe path
Move jsonutils into their own file
kill some dead code
* Add templates to these bois
* remove some code for generating defaults, reorder defaults.json a tad
* Make guid a std::optional
* Large block of PR feedback
* Remove some dead code
* add some comments
* tag some todos
* stl is love, stl is life
* Serialize the source key
* Make the Azure cloud shell a dynamic profile
* Make the built-in namespaces public
* Add a mechanism for quick-diffing a profile
This will be used to generate the json snippets for dynamically generated profiles.
* Generate partial serializations of dynamic profiles _not_ in the user settings
* Start writing tests for generating dyn profiles
* dyn profiles generate GUIDs based on _source
* we won't run DPGs when they'd disabled?
* Add more DPG tests - TestDontRunDisabledGenerators
* Don't layer profiles with a source that's also different
* Add another test, DoLayerUserProfilesOnDynamicsWhenSourceMatches
* Actually insert new dynamic profiles into the file
* Minor cleanup of `Profile::ShouldBeLayered`
* Migrate legacy profiles gracefully
* using namespace winrt::Windows::UI::Xaml;
* _Only_ layer dynamic profiles from user settings, never create
* Write a test for migrating dynamic profiles
* Comments for dayssssss
* add `-noprofile`
* Fix the crash that dustin found
* -Encoding ASCII
* Set a profile's default scheme to Campbell
* Fix the tests I regressed
* Update UsingJsonSetting.md to reflect that changes from these PRs
* Change how GenerateGuidForProfile works
* Make AppKeyBindings do its own serialization
* Remove leftover dead code from the previous commit
* Fix up an enormous number of PR nits
* Don't layer a profile if the json doesn't have a GUID
* Fix a test I unfixed
* get rid of extraneous bois{};
* Piles of PR feedback
* Collection of PR nits
* PR nits
* Fix a typo; Update the defaults to match #2378
* Tiny nits
* In-den-taition!
* Some typos, PR nits
* Fix this broken defaults case
* Apply suggestions from code review
Co-Authored-By: Carlos Zamora <carlos.zamora@microsoft.com>
* PR nits
This PR represents the start of the work on Cascading User + default settings, #754.
Cascading settings will be done in two parts:
* [ ] Layered Default+User settings (this PR)
* [ ] Dynamic Profile Generation (#2603).
Until _both_ are done, _neither are going in. The dynamic profiles PR will target this PR when it's ready, but will go in as a separate commit into master.
This PR covers adding one primary feature: the settings are now in two separate files:
* a static `defaults.json` that ships with the package (the "default settings")
* a `profiles.json` with the user's customizations (the "user settings)
User settings are _layered_ upon the settings in the defaults settings.
## References
Other things that might be related here:
* #1378 - This seems like it's definitely fixed. The default keybindings are _much_ cleaner, and without the save-on-load behavior, the user's keybindings will be left in a good state
* #1398 - This might have honestly been solved by #2475
## PR Checklist
* [x] Closes#754
* [x] Closes#1378
* [x] Closes#2566
* [x] I work here
* [x] Tests added/passed
* [x] Requires documentation to be updated - it **ABSOLUTELY DOES**
## Detailed Description of the Pull Request / Additional comments
1. We start by taking all of the `FromJson` functions in Profile, ColorScheme, Globals, etc, and converting them to `LayerJson` methods. These are effectively the same, with the change that instead of building a new object, they are simply layering the values on top of `this` object.
2. Next, we add tests for layering properties like that.
3. Now, we add a `defaults.json` to the package. This is the file the users can refer to as our default settings.
4. We then take that `defaults.json` and stamp it into an auto generated `.h` file, so we can use it's data without having to worry about reading it from disk.
5. We then change the `LoadAll` function in `CascadiaSettings`. Now, the function does two loads - one from the defaults, and then a second load from the `profiles.json` file, layering the settings from each source upon the previous values.
6. If the `profiles.json` file doesn't exist, we'll create it from a hardcoded `userDefaults.json`, which is stamped in similar to how `defaults.json` is.
7. We also add support for _unbinding_ keybindings that might exist in the `defaults.json`, but the user doesn't want to be bound to anything.
8. We add support for _hiding_ a profile, which is useful if a user doesn't want one of the default profiles to appear in the list of profiles.
## TODO:
* [x] Still need to make Alt+Click work on the settings button
* [x] Need to write some user documentation on how the new settings model works
* [x] Fix the pair of tests I broke (re: Duplicate profiles)
<hr>
* Create profiles by layering them
* Update test to layer multiple times on the same profile
* Add support for layering an array of profiles, but break a couple tests
* Add a defaults.json to the package
* Layer colorschemes
* Moves tests into individual classes
* adds support for layering a colorscheme on top of another
* Layer an array of color schemes
* oh no, this was missed with #2481
must have committed without staging this change, uh oh. Not like those tests actually work so nbd
* Layer keybindings
* Read settings from defaults.json + profiles.json, layer appropriately
This is like 80% of #754. Needs tests.
* Add tests for keybindings
* add support to unbind a key with `null` or `"unbound"` or `"garbage"`
* Layer or clear optional properties
* Add a helper to get an optional variable for a bunch of different types
In the end, I think we need to ask _was this worth it_
* Do this with the stretch mode too
* Add back in the GUID check for profiles
* Add some tests for global settings layering
* M A D W I T H P O W E R
Add a MsBuild target to auto-generate a header with the defaults.json as a
string in the file. That way, we can _always_ load the defaults. Literally impossible to not.
* When the user's profile.json doesn't exist, create it from a template
* Re-order profiles to match the order set in the user's profiles.json
* Add tests for re-ordering profiles to match user ordering
* Add support for hiding profiles using `"hidden": true`
* Use the hardcoded defaults.json for the exception->"use defaults" case
* Somehow I messed up the git submodules?
* woo documentation
* Fix a Terminal.App.Unit.Tests failure
* signed/unsigned is hard
* Use Alt+Settings button to open the default settings
* Missed a signed/unsigned
* Some very preliminary PR feedback
* More PR feedback
Use the wil helper for the exe path
Move jsonutils into their own file
kill some dead code
* Add templates to these bois
* remove some code for generating defaults, reorder defaults.json a tad
* Make guid a std::optional
* Large block of PR feedback
* Remove some dead code
* add some comments
* tag some todos
* stl is love, stl is life
* add `-noprofile`
* Fix the crash that dustin found
* -Encoding ASCII
* Set a profile's default scheme to Campbell
* Fix the tests I regressed
* Update UsingJsonSetting.md to reflect that changes from these PRs
* Change how GenerateGuidForProfile works
* Make AppKeyBindings do its own serialization
* Remove leftover dead code from the previous commit
* Fix up an enormous number of PR nits
* Fix a typo; Update the defaults to match #2378
* Tiny nits
* Some typos, PR nits
* Fix this broken defaults case
This commit also transitions our keybinding events and event handlers to a
TypedEventHandler model with an "event args" class, as specified in the
keybinding arguments specification (#1349). In short, every event can be marked
Handled independently, and a Handled event will stop bubbling out to the
terminal. An unhandled event will be passed off to the terminal as a standard
keypress.
This unifies our keybinding event model and provides a convenient place for
binding arguments to live.
Fixes#2285.
Related to #1349, #1142.
* Warn the user when their settings are bad
The start of work on #1348
* Display an error dialog for errors during validation
* Polish for PR
* Add a ton of tests
* Polish the _GetMessageText bits
* Add code to check for duplicate profiles
* Verify that many warnings work at the same time
* comments y'all
* Apply fixes for dustin's thoughts from PR
* Add a proper exception type, use an array instead of a map
* PR Fixes
* Fix x86 build break
* Add a bit on "using the defaults" when we encountering an exception
* remove a redundant variable
* guid->GUID
* Address Michael's PR comments
* Clean up this error text, and catch exceptions better
* Update src/cascadia/TerminalApp/Resources/en-US/Resources.resw
This commit adds some tracelogging (and telemetry) to answer the following questions:
* Do people use padding? If so, what is the common range of values?
* Are people turning off showTabsInTitlebar?
* How many different profiles are in use, and how do they break down between custom and default?
* Are people manually launching specific profiles, or using "default" fairly often?
* Are people using the Azure Cloud Shell connection?
* Are people leveraging the feature added in #2108 (autogenerating GUIDs)?
* Move TerminalApp's resources into the TerminalApp project
This commit also introduces a scoped resource accessor, lightly taken
from microsoft-ui-xaml. It also moves all static UI strings out of
App.cpp and into localizable resources.
Fixes#792.
* 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
* Try making the button RightCustomContent
* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window
* Create a TitlebarControl
* The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
and MMCControl.
* The App instatntiates a TabRowControl at runtime, and either places it in
the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
when the NCIW creates its UI.
* When the NCIW is created, it creates a grid with two rows, one for the
titlebar and one for the app content.
* The MMCControl is only responsible for Min Max Close now, and is closer to
the window implementation.
* The drag bar takes up all the space from the right of the TabRow to the left
of the MMC
* Things that **DON'T** work:
- When you add tabs, the drag bar doesn't update it's size. It only updates
OnSize
- The MMCControl's Min and Max buttons don't seem to work anymore.
- They should probably just expose their OnMinimizeClick and
OnMaximizeClick events for the Titlebar to handle minimizing and
maximizing.
- The drag bar is Magenta (#ff00ff) currently.
- I'm not _sure_ we need a TabRowControl. We could probably get away with
removing it from the UI tree, I was just being dumb before.
* Fix the MMC buttons not working
I forgot to plumb the window handle through
* Make the titlebar less magenta
* Resize the drag region as we add/remove tabs
* Move the actual MMC handling to the TitlebarControl
* Some PR nits, fix the titlebar painting on maximize
* Put the TabRow in our XAML
* Remove dead code in preparation for review
* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though
* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"
This reverts commit e038b5d921.
* This fixes the bottom border but breaks the titlebar painting
* Fix the NC bottom border
* A bunch of the more minor PR nits
* Add a MinimizeClick event to the MMCControl
This works for Minimize. This is what I wanted to do originally.
* Add events for _all_ of the buttons, not just the Minimize btn
* Change hoe setting the titlebar content works
Now the app triggers a callcack on the host to set the content, instead of the host querying the app.
* Move the tab row to the bottom of it's available space
* Fix the theme reloading
* PR nits from @miniksa
* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
Co-Authored-By: Michael Niksa <miniksa@microsoft.com>
* This needed to be fixed, was missed in other PR nits
* runformat
wait _what_
* Does this fix the CI build?
* 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