Commit Graph

3395 Commits

Author SHA1 Message Date
Dustin Howett 79ef7477f2 Migrate OSS up to 704458ee0 2022-09-13 16:37:28 -05:00
James Holderness 704458ee0e
Pass through soft fonts over conpty (#13965)
This PR introduces a mechanism for passing through downloadable soft
fonts to the conpty client, so that we can support DRCS (Dynamically
Redefinable Character Sets) in Windows Terminal.

Soft fonts were first implemented in conhost (with the GDI renderer) in
PR #10011, and were implemented in the DX renderer in PR #13362.

The way this works is by passing through the `DECDLD` sequence
containing the font definition, but with the character set ID patched to
use a hardcoded value (this is to make sure it's not going to override
the default character set). At the same time we send through an `SCS`
sequence to map this character set into the G1 table so we can easily
activate it.

We still need to process the `DECDLD` sequence locally, though, since
the initial character set mapping take place on the host side. This gets
the DRCS characters into our buffer as PUA Unicode characters. Then when
the VT engine needs to output these characters, it masks them with `7F`
to map them back to ASCII, and outputs an `SO` control to activate the
soft font in the conpty client.

## Validation Steps Performed

I've manually tested with a number of soft fonts and applications that
make use of soft fonts. But if you're testing with the VT320 fonts from
the vt100.net collection, note that you'll need to enable the ISO-2022
coding system first, since they use 8-bit C1 controls.
2022-09-13 00:21:06 +00:00
James Holderness f2b361c146
Make sure Terminal state machine always accepts C1 controls (#13969)
When we added support for the `DECAC1` control sequence, which
determines whether `C1` controls are accepted or not, the intention was
that conhost would be making that determination, and Windows Terminal
would always be expected to accept any passed-through `C1` controls.

However, this didn't take into account that a passed-through `RIS`
sequence could end up disabling `DECAC1`, and that would leave Windows
Terminal incapable of processing any `C1` controls. This PR attempts to
fix that oversight.

The `DECAC1` sequence was added in PR #11690, when we disabled `C1`
acceptance by default.

This is a bit of a hack, but I've added a new `AlwaysAcceptC1` mode to
the state machine, which is enabled at startup in the Terminal, and is
never disabled. The parser then just needs to check whether either
`AcceptC1` or `AlwaysAcceptC1` are set.

## Validation Steps Performed

I've manually confirmed the test case in #13968 now works as expected.

Closes #13968
2022-09-12 19:11:45 +00:00
James Holderness 3e6abd37df
Pass through line rendition attributes over conpty (#13933)
This PR introduces a mechanism for passing through line rendition
attributes to the conpty client, so we can support double-width and
double-height text in Windows Terminal.

Line renditions were first implemented in conhost (with the GDI
renderer) in PR #8664, and were implemented in the DX renderer in PR
#13102.

By default this won't add any additional overhead to the conpty output,
but as soon as there is any usage of double-size text, we switch to a
mode in which every line output will be prefixed with a line rendition
sequence. This is to ensure that the line attributes in the client
terminal are always in sync with the host.

Since this does add some overhead to the conpty output, we'd prefer not
to remain in this mode longer than necessary. So whenever there is a
full repaint of the entire viewport, we check to see if all of the lines
are single-width. If that is the case, we can then safely skip the line
rendition sequences in future updates.

One other small optimization is when the conpty update is only writing
out a single character (this is something we already check for). When
that is the case, we can safely skip the line rendition prefix, because
a single character update should never include a change of the line
rendition.

## Validation Steps Performed

I've manually tested that Windows Terminal now passes the double-size
tests in _Vttest_, and also confirmed various edge cases are working
correctly in my own double-size tests.

Closes #11595
2022-09-09 18:34:30 +00:00
Dustin L. Howett 3958c938af
vPack: fix submit branch, add github token from consvc (#13959)
Our Windows branch name changed, and I took this opportunity to resolve
an issue where vpack builds would occasionally fail due to GitHub rate
limiting the Azure DevOps IP addresses.
2022-09-09 13:30:07 -05:00
Dustin Howett eaf81b8220
version: bump to 1.17 on main 2022-09-09 12:25:13 -05:00
Leonard Hecker 124058f276
AtlasEngine: Fix a correctness bug (#13956)
`ATLAS_POD_OPS` doesn't check for `has_unique_object_representations` and so a
bug exists where `CachedCursorOptions` comparisons invoke undefined behavior.
2022-09-09 18:06:06 +02:00
Mike Griese c02bb296f5
Fix til::color::layer_over (#13946)
The color of inactive tab text is incorrect since #13689 due to the introduction
of `til::color::layer_over` which incorrectly calculated the RGB values.

## Validation Steps Performed
* Added unit tests 

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2022-09-09 14:00:25 +00:00
Leonard Hecker 37c159abba
Reduce amount of telemetry events (#13951)
This commit reduces the amount of telemetry during general usage by about half.
8 events that weren't really used anymore were removed.
1 new event was added ("AppInitialized") which will help us investigate #5907.
During review 9 events were found that were incorrectly tagged as perf. data.

## Validation Steps Performed
* Launch Windows Terminal
* The "latency" field "AppInitialized" matches the approx. launch time 
2022-09-09 13:57:49 +00:00
Mike Griese 95a9d8c31b
Fix conhost crashing on `--headless` without `--signal` (#13950)
It's not supported, and it shouldn't be. 

But this is the absolutely most minimal way to get the crash to go away. 

Closes #13914
2022-09-08 23:23:28 +00:00
Dustin L. Howett e682cdad5e
Disable RTTI on TerminalApp and friends (#13947)
When Leonard updated CLI11 in #12658, he imported a version that no
longer requires RTTI. Since CLI11 was the only reason we had enabled
RTTI in any of our projects, we're finally able to turn it off.

|        | TerminalApp.dll | MSIX Package |
| ------ | ---------------:| ------------:|
| Before |         3180KiB |      6545KiB |
| After  |         1970KiB |      6426KiB |
| Delta  |    **-1210KiB** |  **-119KiB** |
2022-09-08 16:40:10 -05:00
Leonard Hecker 6816620a6d
AtlasEngine: Remove experimental tag and add tracing (#13939)
With AtlasEngine being enabled by default in 1.16 Preview it would look weird
if the `useAtlasEngine` option would still be called "experimental".
Additionally we're interested in how many users opt out of useAtlasEngine,
indicating major issues that would require us to disable it by default again.

Related to #13936

## Validation Steps Performed
* Toggling `useAtlasEngine` works as expected 
* Observe new event with TVPP 
2022-09-08 19:21:52 +00:00
Carlos Zamora 1ef4a42762
Polish MarkMode interactions with ExpandSelectionToWord and existing selection (#13893)
- fix: if a selection exists, mark mode should promote the existing selection instead of creating one at the cursor
- fix: mark mode --> move to middle of a word --> ExpandSelectionToWord --> Shift+Right/Left had some weird behavior. Fix that
- fix: Ctrl+enter on random selection clears selection. It should try to treat selection as a URL.

## References
#13854

NOTE: 3b53f3c can be serviced
2022-09-07 16:07:52 +00:00
Sergey 2c341c8deb
Use the tab's active title for `Export Text` (#13915)
Takes title from the tab instead of the TermControl

Closes #13909
2022-09-07 15:50:36 +00:00
Leonard Hecker 666c446bc3
Fix a ControlCore race condition on connection close (#13882)
As noted by the `winrt::event` documentation:
> [...] But for asynchronous events, even after revoking [...], an in-flight
> event might reach your object after it has started destructing.

This is because while adding/removing/calling event handlers might be
thread-safe, there's no guarantee that they run mutually exclusive.

This commit fixes the issue by reverting 6f0f245. Since we never checked
the result of closing a terminal connection anyways, this commit simply drops
the wait on the connection being teared down to ensure #1996 doesn't regress.

Closes #13880

## Validation Steps Performed
* Open tab, close tab, open tab, close tab, open tab, close tab
  * ConPTY 
  * Azure 
* Closing a tab with a huge amount of panes 
* Opening a bunch of tabs and then closing the window 
* Closing a tab while it's busy with VT 
* `wtd -w 0 nt cmd /c exit` 
* `wtd -w -1 cmd /c exit`
  * No WerFault spawns 
2022-09-06 21:36:59 +00:00
James Holderness 276405a476
Add support for DECBKM (Backarrow Key Mode) (#13894)
This PR adds support for the `DECBKM` sequence, which provides a way for
applications to specify whether the `Backspace` key should generate a
`BS` character or a `DEL` character.

On the original VT100 terminals, the `Backarrow` key generated a `BS`,
and there was a separate `Delete` key that generated `DEL`. However, on
the VT220 and later, there was only the `Backarrow` key. By default it
generated `DEL`, but from the VT320 onwards there was an option to make
it generate `BS`, and the `DECBKM` sequence provided a way to control
that behavior programmatically.

On modern terminals, the `Backspace` key serves as the equivalent of the
VT `Backarrow`, and typically generates `DEL`, while `Ctrl`+`Backspace`
generates `BS`. When `DECBKM` is enabled (for those that support it),
that behavior is reversed, i.e. `Backspace` generates `BS` and
`Ctrl`+`Backspace` generates `DEL`.

This PR also gets the other `Backspace` modifiers more closely aligned
with the expected behavior for modern terminals. The `Shift` modifier
typically has no effect, and the `Alt` modifier typically prefixes the
generated sequence with an `ESC` character.

While not strictly related to `DECBKM`, I noticed while testing that the
`_SetInputMode` method was doing unnecessary work that was specific to
the `FocusEvent` mode. I've now moved that additional processing into
the `EnableFocusEventMode` method, which I think makes things somewhat
simpler.

## Validation Steps Performed

I've tested the basic `DECBKM` functionality in Vttest, and I've
manually tested all the modifier key combinations to make sure they
match what most modern terminals generate.

I've also added a unit test that confirms that the expected sequences
are generated correctly when the `DECBKM` mode is toggled.

Closes #13884
2022-09-06 18:23:54 +00:00
Leonard Hecker 813286c523
AtlasEngine: Fix various bugs found in testing (#13906)
In testing the following issues were found in AtlasEngine and fixed:
1. "Toggle terminal visual effects" action not working
2. `d2dMode` failed to work with transparent backgrounds
3. `GetSwapChainHandle()` is thread-unsafe due to it being called outside
  of the console lock and with single-threaded Direct2D enabled
4. 2 swap chain buffers are less performant than 3
5. Flip-Discard and `Present()` is less energy efficient than
  Flip-Sequential and `Present1()`
6. `d2dMode` used to copy the front to back buffer for partial rendering,
  but always redraw the entire dirty region anyways
7. Added support for DirectX 9 hardware
8. If custom shaders are used not all pixels would be presented

Closes #13906

## Validation Steps Performed
1. Toggling visual effects runs retro shader 
   With a custom shader set, it toggles the shader 
   Toggling `experimental.rendering.software` toggles the shader 
2. `"backgroundImage": "desktopWallpaper"` works with D2D  and D3D 
3. Adding a `Sleep(3000)` in `_AttachDxgiSwapChainToXaml` doesn't break
   Windows 10  nor Windows 11 
4. Screen animations run at 144 FPS  even while moving the window 
5. No weird artefacts during cursor movement or scrolling 
6. No weird artefacts during cursor movement or scrolling 
7. Forcing DirectX 9.3 in `dxcpl` runs fine 
2022-09-02 22:10:09 +00:00
Carlos Zamora bfd5248a2e
Revert "Remove most uses of `CompareInBounds` (#13244)" (#13907)
This reverts commit f785168aac (PR #13244)

The error logged to NVDA was caused by the following line of code in `_getTextValue()`:
`THROW_HR_IF(E_FAIL, !bufferSize.IsInBounds(_start) || !bufferSize.IsInBounds(_end));`
NVDA would expand a text range to encompass the document in the alt buffer. This means that the "end" would be set to the dangling "endExclusive" point (x = left, y = one past the end of the buffer). This is a valid range!
However, upon extracting the text, we would hit the code above. The exclusive end doesn't actually point to anything in the buffer, so we would falsly throw `E_FAIL`.

Though this could be fixed by adding a special check for the `endExclusive` in the line above, I suspect there are other places throughout the UIA code that hit this problem too. The safest course of action is to revert this commit entirely since it was a code health commit (it doesn't actually close an issue).

Closes #13866
2022-09-02 21:25:09 +00:00
Mike Griese fe0d57071e
An attempted fix for the `SignalTextChanged` crash (#13876)
This is conjecture - I was totally unable to repro the original crash here.
Based on the stacks in MSFT:39994969, it looks like we try to fire off a
`RaiseAutomationEvent`, which calls through UIA core, eventually to the point of
calling `ComPtr<WUX::Automation::Peers::IAutomationPeer>::{dtor}`. I'm guessing
based on the stacks that the TermControl has already been released and cleaned
up. However, the lambda in the `RunAsync` calls here only takes a ref to the
TCAP. The TCAP has an outstanding reference (maybe on the other side of the UIA
fence), and gets successfully resolved as strong, but when calling to
`RaiseAutomationEvent`, the `owner` we passed in is gonezo.

This explicitly passes a `weak_ref` to `TermControlAutomationPeer`, rather than
a raw ptr, so we can actually check if the control is still alive before _we_
dereference it. If it is, great, we've got a strong ref to it now and it won't
get torn down.

Again, this is hearsay. Without a repro, the only way we can confirm this is
gone is by just hoping the crashes go away. 🤞

* Might close #13357 (we'll reopen if it doesn't?)
* narrator still works
2022-09-02 10:51:59 +00:00
Carlos Zamora 284d0456ae
Fix crash on save in rejuv'd Color Schemes page (#13902)
## Summary of the Pull Request
Fix a bug where if you pressed the "Save" button, WT would crash. This was caused by adding the possibility that no color scheme is selected in the main page. With no "current scheme", attempting to get its "name" would cause a null ptr exception.

The fix is simple: just check if we actually have a current scheme.
Bonus points: if we don't have a current scheme, don't bother looking throught the color schemes for a match because we'll never find one.


## References
#13269 - Color Schemes Rejuv
2022-09-01 20:40:37 +00:00
Dustin L. Howett fecccaa257
atlas: only enable continuous redraw if the shader needs it (#13903)
We do this by detecting whether the shader is using variable 0 in
constant buffer 0 (typically "time", but it can go by many names.)

Closes #13901
2022-09-01 19:30:35 +00:00
Mike Griese 81ac9765fc
Remove the 1px gap under inactive tabs (#13897)
As noted in https://github.com/microsoft/microsoft-ui-xaml/issues/7674#issuecomment-1234088616

Screenshot below.

* [x] Closes a single element of #13725
2022-09-01 17:25:14 +00:00
Dan Thompson d11ea72639
Implement EnableColorSelection (#13429)
## Summary of the Pull Request

As described in #9583, this change implements the legacy conhost "EnableColorSelection" feature.

## Detailed Description of the Pull Request / Additional comments

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to #13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #9583
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed *(what would be the right place to add tests for this?)*
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated. *(is this needed?)*
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Validation Steps Performed
Just manual testing.
2022-08-31 23:54:29 +00:00
Leonard Hecker a440e15744
Call UpdateJumplist only if the settings changed (#13692)
This commit stores a hash of the `settings.json` file in `ApplicationState`
with which we can detect whether the settings contents actually changed.
Since I only use a small 64-bit hash as opposed to SHA2 for instance,
I'm taking the last write time of the file into account as well.
This allows us to skip calling `UpdateJumplist` at least the majority of app
launches which hopefully improves launch performance on devices with slower IO.

Part of #5907.

## Validation Steps Performed


* Delete some profiles (see above), save settings, tasks are gone 
  FYI For some (...) inexplicable reason, shell task lists are preserved forever
  even if msix applications are uninstalled, etc. So to test whether tasks are
  properly written on first app launch we have to delete some profiles/tasks
  first, otherwise we can't see whether they're actually written later.
* Now exit Windows Terminal, delete `settings.json` and relaunch
* All tasks are back 
* With a debugger, ensure that `CascadiaSettings::WriteSettingsToDisk`
  generates the same hash that `LoadAll` reads. 
2022-08-31 16:17:58 -05:00
PankajBhojwani 7076613374
Rejuvenate the color schemes page (#13269)
Update the color schemes page with the new Win 11 style.
With the rejuvenated experience, we now have two pages:

- `ColorSchemes.xaml`: "color scheme selection" page
	- This is the starting page for the "color schemes" nav view
	  item. It is intended to have the user select a color scheme
	  they want to modify. The user can also click the "Add new"
	  button to add a new color scheme or the "delete" button to
	  delete the selected scheme.
	- If a scheme cannot be deleted, the delete button is disabled
	  and a disclaimer is shown.
	- A "set as default" button sets the selected scheme as the
	  color scheme for profiles.default (aka "base layer"). 
	- The list view item for each scheme includes the name of the
	  scheme, the default tag (if the scheme is the one set in base
	  layer), a text preview of the foreground/background, and a
	  grid of 16 color chips showing the colors for the scheme.
	- Implementation details:
		- View - `ColorSchemes`:
			- "Enter" --> edit the selected scheme
			- "Delete" --> delete the selected scheme
			- if the selected scheme cannot be deleted, we
			  show the disclaimer
		- View model - `ColorSchemesPageViewModel`
			- when possible, the XAML binds directly to the
			  view model functions. Thus, we include logic
			  to delete, edit, and set the selected scheme
			  as default.
			- store the current page, so that we know which
			  page to navigate to upon saving/discarding
			  changes.
- `EditColorScheme.xaml`: "color scheme modification" page
	- a terminal preview of the color scheme is shown at the top of
	  the page.
	- all colors for the scheme are displayed as color chips in an
	  expander that starts as expanded.
	- renaming a color scheme is also inside an expander, but
	  there's no need for "renaming mode" anymore
	- Implementation details:
		- View - `EditColorScheme`:
			- include logic to display the disclaimer and
			  add the automation properties
			- include logic for "Enter" and "Escape" in the
			  rename editor
		- View Model - `ColorSchemeViewModel`:
			- as before, when possible, the XAML binds
			  directly to the view model functions.
			- To enable the "default" tag functionality, we
			  had to expose knowledge of being the default
			  via "IsDefaultScheme()" which compares the
			  current name to the one in the settings model.
- Miscellaneous implementation details:
	- to get the expander to start as expanded, we had to modify the
	  setting container style.
	- Since "set as default" is a button on the selector page, we
	  needed a way to refresh the view model's knowledge of being
	  the default. So we added a `RefreshIsDefault` API to the
	  `ColorSchemeViewModel` to notify changes.
	- With the new layout, we no longer need an 'enter rename mode'
	  button, so all that logic has been removed
	- Add logic to `MainPage` to handle navigating to the correct
	  page upon saving/discarding changes.

Closes #9775

Co-authored-by: Carlos Zamora <cazamor@microsoft.com>
2022-08-31 14:15:10 -07:00
Mike Griese 36f67d7627
Fixes the color of the dropdown arrow in weird themes (#13871)
See also:
33732458ed/dev/SplitButton/SplitButton.xaml (L290-L293)

We need to 
* Also set `SplitButtonForegroundSecondary` cause SplitButton's use that resource separately from the `Foreground()` property
* Manually trigger the visual state change, to refresh the brushes. We do something similar in TabBase

This is one of the bullet points in #13725
2022-08-31 21:03:17 +00:00
Leonard Hecker a96a5b7e79
AtlasEngine: Add support for SetSoftwareRendering (#13886)
This commit implements support for `experimental.rendering.software`.
There's not much to it. It's just another 2 if conditions.

## Validation Steps Performed
* `"experimental.rendering.software": false` renders with D3D 
* `"experimental.rendering.software": true` triggers the new code path 
2022-08-31 13:47:52 -07:00
Leonard Hecker 83aff8d6f0
AtlasEngine: Implement support for custom shaders (#13885)
This commit implements support for custom shaders in AtlasEngine
(`experimental.retroTerminalEffect` and `experimental.pixelShaderPath`).
Setting these properties invalidates the device because that made it
the easiest to implement this less often used feature.
The retro shader was slightly rewritten so that it compiles without warnings.

Additionally we noticed that AtlasEngine works well with D3D 10.0 hardware,
so support for that was added bringing feature parity with DxRenderer.

Closes #13853

## Validation Steps Performed
* Default settings (Independent Flip) 
* ClearType (Independent Flip) 
* Retro Terminal Effect (Composed Flip) 
* Use wallpaper as background image (Composed Flip) 
  * Running `color 40` draws everything red 
  * With Retro Terminal Effect 
2022-08-31 21:54:43 +02:00
Sergey cbbd1e8699
Discard empty command histories before discarding LRU non-empty ones (#13869)
When selecting candidate history, priority is given to histories with empty commands list.

I think lazily calling `s_Allocate` will require a ton of rewriting. Also I think it is not an unexpended behavior that buffer is allocated when an application connects.

Closes #13571
2022-08-31 19:14:54 +00:00
Carlos Zamora 11e7bbc1f3
Introduce ExpandSelectionToWord action (#13765)
## Summary of the Pull Request
Introduces a new action `expandSelectionToWord()` which expands the beginning and end of the selection to encompass the word(s) it's on. This was implemented as a conditional keybinding where the key chord is passed through to the terminal if no selection is active (similar to `copy()`).
It is not bound to anything by default.

## PR Checklist
* [x] Closes #8274
* [x] Schema updated.

## Validation Steps Performed
- Scenario in #8274:
	- search for some text in the find dialog
	- ESC to close the dialog
	- execute `expandSelectionToWord()`
	- the new selection encompasses the whole word
- mark mode
	- move onto a word
	- execute `expandSelectionToWord()`
- mouse selection (same as above)
- select a portion of two words --> new selection fully encompasses both words
2022-08-31 19:06:05 +00:00
Leonard Hecker f499e4df9d
AtlasEngine: Improve RDP performance (#13816)
Direct2D is able to detect remote connections and will switch to sending
draw commands across RDP instead of rendering the data on the server.
This reduces the amount of data that needs to be transmitted as well
as the CPU load of the server, if it has no GPU installed.
This commit changes `AtlasEngine` to render with just Direct2D if a software or
remote device was chosen by `D3D11CreateDevice`. Selecting the DXGI adapter the
window is on explicitly in the future would allow us to be more precise here.

This new rendering mode doesn't implement some of the more fancy features just
yet, like inverted cursors or coloring a single wide glyph in multiple colors.
It reuses most existing facilities and uses the existing tile hash map to cache
DirectWrite text layouts to improve performance. Unfortunately this does incur
a fairly high memory overhead of approximately 25MB for a 120x30 viewport.

Additional drive-by changes include:
* Treat the given font size exactly as its given without rounding
  Apparently we don't really need to round the font size to whole pixels
* Stop updating the const buffer on every frame
* Support window resizing if `debugGeneralPerformance` is enabled

Closes #13079

## Validation Steps Performed
* Tested fairly exhaustively over RDP 
2022-08-31 20:35:19 +02:00
Mike Griese 0b1b7e673b
Update the default themes for 1.16 (#13743)
More or less, as in #13554 

* Dark theme by default (was `system`)
  * Justification:
    > I think the interesting thing that we have today is that the color
    > scheme is dark by default, but our window theme is set to system.
    > System theme in Windows 11 is defaulted to light unless changed by
    > the user. Now, we have a conflict between the theme and color scheme
    > in Terminal.
    > 
    > I think our options become, make the color scheme match "default"
    > and set it to a light color scheme if the system theme is light, or
    > manually match the theme to the color scheme by setting it to dark.
    > 
    > Given that Terminal has historically had a black background with
    > its Campbell color scheme, for a consistent UI experience, I'm
    > voting to change the window theme to be dark by default as well.
* `tab.background: terminalBackground` 
* Change the tab row colors back to "what they were pre-Controlsv2" more
  or less
  - The ramp is based off of "Light tab row background from Edge's
    unfocused titlebar color, inactive tab row color BG from the
    controlsv1 colors"
* `tabRow.unfocusedBackground` set `Transparent`

Closes #13554
2022-08-31 13:32:32 -05:00
Mike Griese f07b9e195e
Add support for `tab.unfocusedBackground` (#13689)
Does what it sounds like on the label.

This is important, because when unset, the tab will use the active `Background` color to create an inactive BG, which maybe isn't what we want. Consider: 
- a bright cyan active BG,
- and `terminalBG` for the `tabRow` bg.

Without an unfocusedBackground setting, all the tabs will still appear cyan when unfocused, which is extra gross. 

As a judgement call, I made `terminalBackground` and `accent` use 30% opacity when set, to match the existing coloration. 

See also #13554. If we want to make the default theme `tab.background: terminalBackground`, we should make `tab.unfocusedBackground` transparent (`#00000000`) by default. Otherwise, a Campell (`#0c0c0c`) tab on _any_ tab row will still have a faint tab visible. 

* closes #13684
* closes #13246
* tested manually

This also does a lot of code shuffling, to get SettingsUI tabs to behave sensibly. We want those tabs to have (`#0c0c0c`, `#ffffff`) colored BGs for `terminalBackground` (see mail thread). 

We also don't want dark focused tabs colors, combined with light tab row colors, combined with transparent unfocused tabs, to result in unfocused tabs having white-on-white text. That's gross. So that's been added to this PR in b38b704.
2022-08-31 12:48:03 -05:00
Jamie Magee 3ae67a9b68
Add `$schema` to `cgmanifest.json` (#13887)
This pull request adds the JSON schema for `cgmanifest.json`.

## FAQ

### Why?

A JSON schema helps you to ensure that your `cgmanifest.json` file is valid.
JSON schema validation is a build-in feature in most modern IDEs like Visual Studio and Visual Studio Code.
Most modern IDEs also provide code-completion for JSON schemas.

### How can I validate my `cgmanifest.json` file?

Most modern IDEs like Visual Studio and Visual Studio Code have a built-in feature to validate JSON files.
You can also use [this small script](https://github.com/JamieMagee/verify-cgmanifest) to validate your `cgmanifest.json` file.

### Why does it suggest camel case for the properties?

Component Detection is able to read camel case and pascal case properties.
However, the JSON schema doesn't have a case-insensitive mode.
We therefore suggest camel case as it's the most common format for JSON.

### Why is the diff so large?

To deserialize the `cgmanifest.json` file, we use [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
However, to serialize the JSON again we use [`prettier`](https://prettier.io/).
We found that, in general, it gave smaller diffs than the default [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) function.
2022-08-31 17:31:24 +00:00
Leonard Hecker 12122b2bf9
Fix a race condition in UpdatePatternLocations (#13859)
Since locking the console can take a non-trivial amount of time,
the main thread might have already released the ControlCore instance, while the
`UpdatePatternLocations` background thread is holding the last active reference.
If the function call goes out of scope, we destroy the instance, which might
not be safe, considering its members are usually only used by the main thread.
This commit fixes the issue by only holding a reference of the `Terminal`.

## Validation Steps Performed
* Patterns are recognized 
2022-08-30 20:20:05 +00:00
Mike Griese a85d9e69ed
Attempt to fix the _refreshSizeUnderLock crash (#13857)
See https://github.com/microsoft/terminal/issues/12176#issuecomment-1199488906, and MSFT:39723014.

I have literally no idea how to repro this one, or debug it. The dump I looked at looked like there was a `SwapChainScaleChanged` that was being dispatched as the app was tearing down. The `ControlCore` had started closing, but the `TermControl` hadn't yet. Apparently, just none of the `_refreshSizeUnderLock` callers checked if we were already closing.

All the callers appear to be on the main thread.

Closes #12176

Since there's no real way for me to repro this manually, I'm thinking we fire this fix off to the OS terminal build, where we'll pretty quickly be able to see if this fixed it or not.
2022-08-29 21:42:17 +00:00
Mike Griese 19b6d351a5
Remove the `useMica` key (#13872)
It's not making it for 1.16, so it's out.
Closes a bullet point in #13725
2022-08-29 21:38:02 +00:00
Leonard Hecker 76a5ff143e
Stop throwing exceptions for FontIcons (#13858)
While having a debugger attached, opening the settings tab generates an
uncomfortable amount of exceptions. This change reduces this by a lot.

## Validation Steps Performed
* Icons still appear 
2022-08-29 21:17:36 +00:00
Jeroen B 0ca1356859
Add action for closing all unfocused panes (#13547)
This PR introduces a new action for closing all unfocused / other panes within a tab.

**Edit (17-08-2022):** Read-only panes are ignored when this action is being used (i.e., left open).

![gif](https://user-images.githubusercontent.com/27634653/180733229-0c8e6427-c586-4fe1-b6fd-a2b1c94734e5.gif)

## Validation Steps Performed

The action was manually tested by applying it to various 'compositions' of panes. This includes tests on read-only panes.

Closes #12216
2022-08-26 17:27:04 +00:00
Mike Griese 7e47f6aab9
Wire up passing LNK/EXE data from OpenCon to ITerminalHandoff (#13570)
This PR by itself doesn't _really_ change much. Technically, now the Terminal will respect the Title of a `.lnk` when started for defterm, but we don't do anything else yet. Primarily, the goal of this PR is to just wire up startup info in OpenConsole to the connected Terminal. 
* This required a bit of changes in `srvinit.cpp:ConsoleEstablishHandoff` to replicate other bits of startup, where we crack open the connect message to get the relevant bits of info.
* We pack that all into a `TERMINAL_STARTUP_INFO`, which we pass along to the registered terminal application.
* `ConptyConnection` accepts the handoff, and gathers that information out of the `TERMINAL_STARTUP_INFO`
* Some other updates to the scratch sln were made to make it build again (related, but unimportant).
* This is a precursor to:
  * #13111
  * #12154
* Closes #9458
* Tested manually
* I work here
2022-08-26 06:16:29 -05:00
Carlos Zamora deb5e7c650
[a11y] Make CommandPalette announce selected item (#13519)
## Summary of the Pull Request
The command palette (and tab search by extension) doesn't ever tell screen readers what is selected. Here, we simply hook up the selection changed event to a function that tells the screen reader what is selected. With this, the user no longer has to tab into the list view to know what is selected!

Will resolve the following bug upon validation from a11y team: #12065 

## Validation Steps Performed
Performed repro steps from #12065.

NOTE: we do NOT read the selected item when the command palette is first opened. I think that's ok.
2022-08-26 00:11:37 +00:00
Dustin L. Howett 623a59ecaa
release yml: name the package correctly, don't duplicate appx (#13852)
I got tired of renaming the packages that came out of our build
pipeline. I also got tired of the fact that every appxbundle artifact we
upload comes with another whole copy of Terminal for every architecture,
plus all their symbols. Those are reflected in other artifacts, so
there's no reason to duplicate them.
2022-08-25 17:46:06 -05:00
Carlos Zamora 4488a25971
[Follow-up] Polish keyboard navigation to hyperlinks (#13494)
## Summary of the Pull Request
Polishes #13405 with some additional feedback found in testing and post-mortem reviews. Such feedback includes:
- [x] ControlInteractivity vs ControlCore split ([link](https://github.com/microsoft/terminal/pull/13405#discussion_r919365435))
- [x] clearing the selection should be under lock when copying text via "Enter"
- [x] move mark mode keybindings into a helper function
- [x] decide if "Enter" should be configurable or non-configurable ([link](https://github.com/microsoft/terminal/pull/13405#discussion_r919379305))
- [x] rename `_isTargetingUrl`
- [x] bugfix: ctrl+enter when the link is outside of the viewport

## References
Original PR: #13405
Relevant issue: #6649
Epic: #4993
2022-08-25 18:53:45 +00:00
Carlos Zamora b4ada09776
[UIA] Prevent erroneous `L'\0'` padding in `GetText(INT_MAX)` (#13779)
Apparently, calling `GetText(INT_MAX)` causes a HUGE memory spike for a few seconds each time this is called. The [UIA docs](https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nf-uiautomationcore-itextrangeprovider-gettext#parameters) say to put `-1` if no limit is required, but I assume a few people have been hit by this before.

This addresses this issue (and similar ones) in two ways:
1. as we iterate over the lines of text, if we're already past the max length, just break out of the loop
2. _only_ resize if the max length is actually less than the current length. This prevents us padding the string with `L'\0'` erroneously (which is probably what causes the memory spike).
2022-08-25 17:04:52 +00:00
Mike Griese 94339c10e5
Fix a subtle issue with PropertyChanged in ViewModels (#13839)
While debugging #13694, we discovered a very subtle bug we had accidentally introduced in a few places. `ViewModelHelper` defines a `PropertyChanged` event, backed by a `_propertyChangedHandlers` `event`. All opbservable properties in the viewmodels are supposed to run through that event. However, if you do `WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler)` in a derived class, it'll override that original method with the new one. XAML will subscribe to the second one, which is backed by `_PropertyChangedHandlers`, but the properties will still raise notifications on the callbacks registered to `_propertyChangedHandlers`. 

This change makes it more explicit in these derived classes, that the `PropertyChanged` method exposed by these classes is indeed the one that's implemented in the base class. 

This is a bit of a footgun, for sure. AuditMode would have apparently caught this, as we'd be overriding a method without using the `override` keyword.

Unblocks #13694.
2022-08-25 14:00:32 +00:00
Junyoung Lee 3d36017ee1
Disable "Always show tabs" when "Hide the title bar" is enabled (#13694)
In Global Appearance SUI, the toggle switch for "Always show tabs" is now grayed out when "Hide the title bar" is enabled (the default).

Also, the order of the settingcontainers was changed to help show the cause and effect more. See [this comment](https://github.com/microsoft/terminal/issues/12873#issuecomment-1094928881).

Closes #12873
2022-08-25 13:57:11 +00:00
Leonard Hecker 3ab859b8d1
AtlasEngine: Round cell sizes to nearest instead of up (#13833)
After some deliberation I noticed that rounding the glyph advance up to yield
the cell width is at least just as wrong as rounding it. This is because
we draw glyphs centered, meaning that (at least in theory) anti-aliased
pixels might clip outside of the layout box on _both_ sides of the glyph
adding not 1 but 2 extra pixels to the glyph size. Instead of just `ceilf`
we would have had to use `ceilf(advanceWidth / 2) * 2` to account for that.

This commit simplifies our issue by just going with what other applications do:
Round all sizes (cell width and height) to the nearest pixel size.

Closes #13812

## Validation Steps Performed
* Set a breakpoint on `scaling Required == true` in `AtlasEngine::_drawGlyph`
* Test an assortment of Cascadia Mono, Consolas, MS Gothic, Lucida Console
  at various font sizes (6, 7, 8, 10, 12, 24, ...)
* Ensure breakpoint isn't hit 
  This tells us that no glyph resizing was necessary
2022-08-24 22:18:23 +00:00
Leonard Hecker 4f3afee728
Fix two race conditions around pseudo window visibility (#13832)
This commit fixes two race conditions:
* `SetPseudoWindowCallback` set the `_pseudoWindowMessageCallback`
  callback after the Win32 message thread was already spawned.
  This issue was fixed by instead using the `ServiceLocator` to get
  a hold of the global `VtIo` instance which is created statically.
* `XtermEngine::SetWindowVisibility` was called without holding the
  console lock. This issue was fixed by simply acquiring it first.

Closes MSFT:40913882

## Validation Steps Performed
* Add `IsConsoleLocked()` assertion in `VtEngine::_Write`
* Run Windows Terminal
* No assertion failures 
2022-08-24 00:06:02 +00:00
Carlos Zamora 70313db246
Make Mark Mode keybindings precede custom keybindings (#13659)
## Summary of the Pull Request
This PR moves the key handling for mark mode into a helper method that is then called before an action/key binding is attempted. 

## References
Epic: #4993 
Closes #13533

## Validation Steps Performed
- Add custom keybinding to "down" arrow key
- in mark mode --> selection updates appropriately
- out of mark mode --> keybinding executed
2022-08-22 20:39:23 +00:00
Dustin L. Howett 2dedc9af7f
Use the viewport-relative cursor pos for CCore.CursorPosition (#13785)
In #13024, we removed `Terminal::GetCursorPosition` from TerminalCore.
This has been widely regarded as a good move.

Now, you might rightly be wondering: why didn't compilation immediately
fail? Well. It turns out that there were _two_ copies of
`GetCursorPosition`. One for `const Terminal`, and one for `Terminal`.
This is important.

`Terminal::GetCursorPosition()` returned the cursor position relative to
the viewport. `Terminal::GetCursorPosition() const`, however, returns
the cursor position in absolute.

We removed the non-`const` one. Fortunately, thanks to the lookup rules
for `const`-qualified members, this didn't matter. Code that called
`GetCursorPosition()` still called `GetCursorPosition()`, and everything
was fine.

Except that part about the relative coordinates. That was not fine.

The TSF control is the _only_ consumer of `ControlCore.CursorPosition`,
and that was the _only_ consumer of relative-`GetCursorPosition()`.

This commit restores equilibrium by introducing a new
`GetViewportRelativeCursorPosition()` member to `Terminal` and switching
over the only consumer of relative cursor position to use it.

Closes #13769.
2022-08-22 11:58:40 -05:00