Instead of having a separate method for setting each mouse and keyboard
mode, this PR consolidates them all into a single method which takes a
mode parameter, and stores the modes in a `til::enumset` rather than
having a separate `bool` for each mode.
This enables us to get rid of a lot of boilerplate code, and makes the
code easier to extend when we want to introduce additional modes in the
future. It'll also makes it easier to read back the state of the various
modes when implementing the `DECRQM` query.
Most of the complication is in the `TerminalInput` class, which had to
be adjusted to work with an `enumset` in place of all the `bool` fields.
For the rest, it was largely a matter of replacing calls to all the old
mode setting methods with the new `SetInputMode` method, and deleting a
bunch of unused code.
One thing worth mentioning is that the `AdaptDispatch` implementation
used to have a `_ShouldPassThroughInputModeChange` method that was
called after every mode change. This code has now been moved up into the
`SetInputMode` implementation in `ConhostInternalGetSet` so it's just
handled in one place. Keeping this out of the dispatch class will also
be beneficial for sharing the implementation with `TerminalDispatch`.
## Validation
The updated interface necessitated some adjustments to the tests in
`AdapterTest` and `MouseInputTest`, but the essential structure of the
tests remains unchanged, and everything still passes.
I've also tested the keyboard and mouse modes in Vttest and confirmed
they still work at least as well as they did before (both conhost and
Windows Terminal), and I tested the alternate scroll mode manually
(conhost only).
Simplifying the `ConGetSet` and `ITerminalApi` is also part of the plan
to de-duplicate the `AdaptDispatch` and `TerminalDispatch`
implementation (#3849).
## Summary of the Pull Request
The deadlock was caused by `ScreenInfoUiaProviderBase::GetSelection()` calling `TermControlUiaProvider::GetSelectionRange` (both of which attempted to lock the console). This PR removes the lock and initialization check from `TermControlUiaProvider`. It is no longer necessary because the only one that calls it is `SIUPB::GetSelection()`.
Additionally, this adds some code that was useful in debugging this race condition. That should help us figure out any locking issues that may come up in the future.
## References
#11312Closes#11385
## Validation Steps Performed
✅ Repro steps don't cause hang
Adds a check before every UIA function call to ensure the terminal (specifically the buffer) is initialized before doing work. Both the `ScreenInfoUiaProvider` and the `UiaTextRange` are now covered.
## References
Closes#11135#10971 & #11042
## Detailed Description of the Pull Request / Additional comments
Originally, I tried applying this heuristic to all the `RuntimeClassInitialize` on `UiaTextRangeBase` with the philosophy of "a range pointing to an invalid buffer is invalid itself", but that caused a regression on [MSFT 33353327](https://microsoft.visualstudio.com/OS/_workitems/edit/33353327).
`IUiaData` also has `GetTextBuffer()` return a `TextBuffer&`, which cannot be checked for nullness. Instead, I decided to add a function to `IUiaData` that checks if we have a valid state. Since this is shared with Conhost and Conhost doesn't have this issue, I simply make that function say that it's always in a valid state.
## Validation Steps Performed
- [X] Narrator can detect newly created terminals
- [X] (On Windows Server 2022) Windows Terminal does not hang on launch
Implements the following keyboard selection non-configurable key bindings:
- shift+arrow --> move endpoint by character
- ctrl+shift+left/right --> move endpoint by word
- shift+home/end --> move to beginning/end of line
- ctrl+shift+home/end --> move to beginning/end of buffer
This was purposefully done in the ControlCore layer to make keyboard selection an innate part of how the terminal functions (aka a shared component across terminal consumers).
## References
#715 - Keyboard Selection
#2840 - Spec
## Detailed Description of the Pull Request / Additional comment
The most relevant section is `TerminalSelection.cpp`, where we define how each movement operates. It's basically a giant embedded switch-case statement. We leverage a lot of the work done in a11y to perform the movements.
## Validation Steps Performed
- General cases:
- test all of the key bindings added
- Corner cases:
- `char`: wide glyph support
- `word`: move towards, away, and across the selection pivot
- automatically scroll viewport
- ESC (and other key combos) are still clearing the selection properly
## Summary of the Pull Request
This adds a new setting `intenseTextStyle`. It's a per-appearance, control setting, defaulting to `"all"`.
* When set to `"all"` or `["bold", "bright"]`, then we'll render text as both **bold** and bright (1.10 behavior)
* When set to `"bold"`, `["bold"]`, we'll render text formatted with `^[[1m` as **bold**, but not bright
* When set to `"bright"`, `["bright"]`, we'll render text formatted with `^[[1m` as bright, but not bold. This is the pre 1.10 behavior
* When set to `"none"`, we won't do anything special for it at all.
## references
* I last did this in #10648. This time it's an enum, so we can add bright in the future. It's got positive wording this time.
* ~We will want to add `"bright"` as a value in the future, to disable the auto intense->bright conversion.~ I just did that now.
* #5682 is related
## PR Checklist
* [x] Closes#10576
* [x] I seriously don't think we have an issue for "disable intense is bright", but I'm not crazy, people wanted that, right? https://github.com/microsoft/terminal/issues/2916#issuecomment-544880423 was the closest
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/381
## Validation Steps Performed
<!-- ![image](https://user-images.githubusercontent.com/18356694/125480327-07f6b711-6bca-4c1b-9a76-75fc978c702d.png) -->
![image](https://user-images.githubusercontent.com/18356694/128929228-504933ee-cf50-43a2-9982-55110ba39191.png)
Yea that works. Printed some bold text, toggled it on, the text was no longer bold. hooray.
### EDIT, 10 Aug
```json
"intenseTextStyle": "none",
"intenseTextStyle": "bold",
"intenseTextStyle": "bright",
"intenseTextStyle": "all",
"intenseTextStyle": ["bold", "bright"],
```
all work now. Repro script:
```sh
printf "\e[1m[bold]\e[m[normal]\e[34m[blue]\e[1m[bold blue]\e[m\n"
```
`SRWLOCK`, as used by `std::shared_mutex`, is a inherently unfair mutex
and makes no guarantee whatsoever whether a thread may acquire the lock
in a timely manner. This is problematic for our renderer which relies on
being able to acquire the lock in a timely and predictable manner.
Drawing stalls of up to one minute have been observed in tests.
This issue can be solved with a primitive ticket lock, which is 10x
slower than a `SRWLOCK` but still sufficiently fast for our use case
(10M locks per second per thread). It's likely that any non-trivial lock
duration will diminish the difference to "negligible".
## Validation Steps Performed
* It still blends ✔️
## Summary of the Pull Request
This implements `GetAttributeValue` and `FindAttribute` for `UiaTextRangeBase` (the shared `ITextRangeProvider` for Conhost and Windows Terminal). This also updates `UiaTracing` to collect more useful information on these function calls.
## References
#7000 - Epic
[Text Attribute Identifiers](https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-textattribute-ids)
[ITextRangeProvider::GetAttributeValue](https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nf-uiautomationcore-itextrangeprovider-getattributevalue)
[ITextRangeProvider::FindAttribute](https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nf-uiautomationcore-itextrangeprovider-findattribute)
## PR Checklist
* [X] Closes#2161
* [X] Tests added/passed
## Detailed Description of the Pull Request / Additional comments
- `TextBuffer`:
- Exposes a new `TextBufferCellIterator` that takes in an end position. This simplifies the logic drastically as we can now use this iterator to navigate through the text buffer. The iterator can also expose the position in the buffer.
- `UiaTextRangeBase`:
- Shared logic & helper functions:
- Most of the text attributes are stored as `TextAttribute`s in the text buffer. To extract them, we generate an attribute verification function via `_getAttrVerificationFn()`, then use that to verify if a given cell has the desired attribute.
- A few attributes are special (i.e. font name, font size, and "is read only"), in that they are (1) acquired differently and (2) consistent across the entire text buffer. These are handled separate from the attribute verification function.
- `GetAttributeValue`: Retrieve the attribute verification of the first cell in the range. Then, verify that the entire range has that attribute by iterating through the text range. If a cell does not have that attribute, return the "reserved mixed attribute value".
- `FindAttribute`: Iterate through the text range and leverage the attribute verification function to find the first contiguous range with that attribute. Then, make the end exclusive and output a `UiaTextRangeBase`. This function must be able to perform a search backwards, so we abstract the "start" and "end" into `resultFirstAnchor` and `resultSecondAnchor`, then perform post processing to output a valid `UiaTextRangeBase`.
- `UiaTracing`:
- `GetAttributeValue`: Log uia text range, desired attribute, resulting attribute metadata, and the type of the result.
- `FindAttribute`: Log uia text range, desired attribute and attribute metadata, if we were searching backwards, the type of the result, and the resulting text range.
- `AttributeType` is a nice way to understand/record if the result was either of the reserved UIA values, a normal result, or an error.
- `UiaTextRangeTests`:
- `GetAttributeValue`:
- verify that we know which attributes we support
- test each of the known text attributes (expecting 100% code coverage for `_getAttrVerificationFn()`)
- `FindAttribute`:
- test each of the known _special_ text attributes
- test `IsItalic`. NOTE: I'm explicitly only testing one of the standard text attributes because the logic is largely the same between all of them and they leverage `_getAttrVerificationFn()`.
## Validation Steps Performed
- @codeofdusk has been testing this Conhost build
- Tests added for Conhost and shared implementation
- Windows Terminal changes were manually verified using accessibility insights and NVDA
<!-- 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
Adds a global setting, `experimental.detectHyperlinks`, that controls whether we automatically detect links and make them clickable. Default is set to true.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#9981
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [x] Schema updated.
* [x] I work here
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
When `detectHyperlinks` is set to false, links do not underline on hover and are not clickable.
## Summary of the Pull Request
When we parse OSC 9;4, allow a trailing semicolon (i.e. allow `9;4;` or something like `9;4;3;`).
## PR Checklist
* [x] Closes#9960
* [X] Tests added/passed
## Validation Steps Performed
OSC 9;4 sequences with or without trailing semicolons work
## Summary of the Pull Request
Brace yourselves, it's finally here. This PR does the dirty work of splitting the monolithic `TermControl` into three components. These components are:
* `ControlCore`: This encapsulates the `Terminal` instance, the `DxEngine` and `Renderer`, and the `Connection`. This is intended to everything that someone might need to stand up a terminal instance in a control, but without any regard for how the UX works.
* `ControlInteractivity`: This is a wrapper for the `ControlCore`, which holds the logic for things like double-click, right click copy/paste, selection, etc. This is intended to be a UI framework-independent abstraction. The methods this layer exposes can be called the same from both the WinUI TermControl and the WPF control.
* `TermControl`: This is the UWP control. It's got a Core and Interactivity inside it, which it uses for the actual logic of the terminal itself. TermControl's main responsibility is now
By splitting into smaller pieces, it will enable us to
* write unit tests for the `Core` and `Interactivity` bits, which we desparately need
* Combine `ControlCore` and `ControlInteractivity` in an out-of-proc core process in the future, to enable tab tearout.
However, we're not doing that work quite yet. There's still lots of work to be done to enable that, thought this is likely the biggest portion.
Ideally, this would just be methods moved wholesale from one file to another. Unfortunately, there are a bunch of cases where that didn't work as well as expected. Especially when trying to better enforce the boundary between the classes.
We've got a couple tests here that I've added. These are partially examples, and partially things I ran into while implementing this. A bunch of things from #7001 can go in now that we have this.
This PR is gonna be a huge pain to review - 38 files with 3,730 additions and 1,661 deletions is nothing to scoff at. It will also conflict 100% with anything that's targeting `TermControl`. I'm hoping we can review this over the course of the next week and just be done with it, and leave plenty of runway for 1.9 bugs in post.
## References
* In pursuit of #1256
* Proc Model: #5000
* https://github.com/microsoft/terminal/projects/5
## PR Checklist
* [x] Closes#6842
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760249
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760258
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
* I don't love the names `ControlCore` and `ControlInteractivity`. Open to other names.
* I added a `ICoreState` interface for "properties that come from the `ControlCore`, but consumers of the `TermControl` need to know". In the future, these will all need to be handled specially, because they might involve an RPC call to retrieve the info from the core (or cache it) in the window process.
* I've added more `EventArgs` to make more events proper `TypedEvent`s.
* I've changed how the TerminalApp layer requests updated TaskbarProgress state. It doesn't need to pump TermControl to raise a new event anymore.
* ~~Something that snuck into this branch in the very long history is the switch to `DCompositionCreateSurfaceHandle` for the `DxEngine`. @miniksa wrote this originally in 30b8335, I'm just finally committing it here. We'll need that in the future for the out-of-proc stuff.~~
* I reverted this in c113b65d9. We can revert _that_ commit when we want to come back to it.
* I've changed the acrylic handler a decent amount. But added tests!
* All the `ThrottledFunc` things are left in `TermControl`. Some might be able to move down into core/interactivity, but once we figure out how to use a different kind of Dispatcher (because a UI thread won't necessarily exist for those components).
* I've undoubtably messed up the merging of the locking around the appearance config stuff recently
## Validation Steps Performed
I've got a rolling list in https://github.com/microsoft/terminal/issues/6842#issuecomment-810990460 that I'm updating as I go.
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/9706
* [x] CLA signed.
* [ ] Tests added/passed
* [x] Documentation updated here: https://github.com/MicrosoftDocs/terminal/pull/313
* [x] Schema updated.
* [ ] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
Added global flag named `trimBlockSelection` set to `false` by default.
The setting was added to Interactions menu of the SUI.
This pull request adds an appearance configuration object to our
settings model and app lib, allowing the control to be rendered
differently depending on its state, and then uses it to add support for
an "unfocused" appearance that the terminal will use when it's not in
focus.
To accomplish this, we isolated the appearance-related settings from
Profile (into AppearanceConfig) and TerminalSettings (into the
IControlAppearance and ICoreAppearance interfaces). A bunch of work was
done to make inheritance work.
The unfocused appearance inherits from the focused one _for that
profile_. This is important: If you define a
defaults.unfocusedAppearance, it will apply all of defaults' settings to
any leaf profile when a terminal in that profile is out of focus.
Specified in #8345Closes#3062Closes#2316
This pull request introduces Microsoft.Terminal.Core.Color as an
alternative to both Windows.UI.Color and uint32_t/COLORREF in the
TerminalCore, ...Control, ...SettingsModel and ...SettingsEditor layers.
M.T.C.Color is trivially convertible to/from til::color and therefore
to/from COLORREF, W.U.Color, and any other color representation we might
need².
I've replaced almost every use of W.U.Color and uint32_t-as-color in the
above layers, with minor exception¹.
The need for this work is twofold.
First: We cannot bear a dependency from TerminalCore (which should,
on paper, be Windows 7 compatible) on Windows.UI or any other WinRT
namespace.
This work removes one big dependency on Windows.UI, but it does not go
all the way.
Second: TerminalCore chose to communicate mostly in packed uint32s
(COLORREF), which was inherently lossy and dangerous.
¹ The UI layers (TerminalControl, TerminalApp) still use
Windows.UI.Color as they are intimately connected to the UWP XAML UI.
² In the future, we might even be able to *use* the alpha channel...
## PR Checklist
* [x] I ran into the need for this when I introduced cursor inversion
* [X] Fixes a longstanding itch
## Validation Steps Performed
Built and ran all tests for the impacted layers, even the local ones!
**BE NOT AFRAID**. I know that there's 107 files in this PR, but almost
all of it is just find/replacing `TerminalControl` with `Control`.
This is the start of the work to move TermControl into multiple pieces,
for #5000. The PR starts this work by:
* Splits `TerminalControl` into separate lib and dll projects. We'll
want control tests in the future, and for that, we'll need a lib.
* Moves `ICoreSettings` back into the `Microsoft.Terminal.Core`
namespace. We'll have other types in there soon too.
* I could not tell you why this works suddenly. New VS versions? New
cppwinrt version? Maybe we're just better at dealing with mdmerge
bugs these days.
* RENAMES `Microsoft.Terminal.TerminalControl` to
`Microsoft.Terminal.Control`. This touches pretty much every file in
the sln. Sorry about that (not sorry).
An upcoming PR will move much of the logic in TermControl into a new
`ControlCore` class that we'll add in `Microsoft.Terminal.Core`.
`ControlCore` will then be unittest-able in the
`UnitTests_TerminalCore`, which will help prevent regressions like #9455
## Detailed Description of the Pull Request / Additional comments
You're really gonna want to clean the sln first, then merge this into
your branch, then rebuild. It's very likely that old winmds will get
left behind. If you see something like
```
Error MDM2007 Cannot create type
Microsoft.Terminal.TerminalControl.KeyModifiers in read-only metadata
file Microsoft.Terminal.TerminalControl.
```
then that's what happened to you.
Implement the `XTPUSHSGR` and `XTPOPSGR` control sequences (see #1796).
This change adds a new pair of methods to `ITermDispatch`:
`PushGraphicsRendition` and `PopGraphicsRendition`, and then plumbs the
change through `AdaptDispatch`, `TerminalDispatch`, `ITerminalApi` and
`TerminalApi`.
The stack logic is encapsulated in the `SgrStack` class, to allow it to
be reused between the two APIs (`AdaptDispatch` and `TerminalDispatch`).
Like xterm, only ten levels of nesting are supported.
The stack is implemented as a "ring stack": if you push when the stack
is full, the bottom of the stack will be dropped to make room.
Partial pushes (see the description of `XTPUSHSGR` in Issue #1796) are
implemented per xterm spec.
## Validation Steps Performed
Tests added, plus manual verification of the feature.
Closes#1796
## References
* See also #8617
## PR Checklist
* [x] Supports #3075
* [x] I work here.
* [x] Manual test.
## Detailed Description of the Pull Request / Additional comments
### Window Title Generation
Every time the renderer checks the title, it's doing two bad things that
I've fixed:
1. It's assembling the prefix to the full title doing a concatenation.
No one ever gets just the prefix ever after it is set besides the
concat. So instead of storing prefix and the title, I store the
assembled prefix + title and the bare title.
2. A copy must be made because it was returning `std::wstring` instead
of `std::wstring&`. Now it returns the ref.
### Dirty Area Return
Every time the renderer checks the dirty area, which is sometimes
multiple times per pass (regular text printing, again for selection,
etc.), a vector is created off the heap to return the rectangles. The
consumers only ever iterate this data. Now we return a span over a
rectangle or rectangles that the engine must store itself.
1. For some renderers, it's always a constant 1 element. They update
that 1 element when dirty is queried and return it in the span with a
span size of 1.
2. For other renderers with more complex behavior, they're already
holding a cached vector of rectangles. Now it's effectively giving
out the ref to those in the span for iteration.
### Bitmap Runs
The `til::bitmap` used a `std::optional<std::vector<til::rectangle>>`
inside itself to cache its runs and would clear the optional when the
runs became invalidated. Unfortunately doing `.reset()` to clear the
optional will destroy the underlying vector and have it release its
memory. We know it's about to get reallocated again, so we're just going
to make it a `std::pmr::vector` and give it a memory pool.
The alternative solution here was to use a `bool` and
`std::vector<til::rectangle>` and just flag when the vector was invalid,
but that was honestly more code changes and I love excuses to try out
PMR now.
Also, instead of returning the ref to the vector... I'm just returning a
span now. Everyone just iterates it anyway, may as well not share the
implementation detail.
### UTF-8 conversions
When testing with Terminal and looking at the `conhost.exe`'s PTY
renderer, it spends a TON of allocation time on converting all the
UTF-16 stuff inside to UTF-8 before it sends it out the PTY. This was
because `ConvertToA` was allocating a string inside itself and returning
it just to have it freed after printing and looping back around again...
as a PTY does.
The change here is to use `til::u16u8` that accepts a buffer out
parameter so the caller can just hold onto it.
## Validation Steps Performed
- [x] `big.txt` in conhost.exe (GDI renderer)
- [x] `big.txt` in Terminal (DX, PTY renderer)
- [x] Ensure WDDM and BGFX build under Razzle with this change.
This adds "paste filtering" & "bracketed paste mode" to the Windows
Terminal.
I've moved the paste handling code in `TerminalControl` to
`Microsoft::Console::Util` to be able to easily test it, and the paste
transformer from `TerminalControl` to `TerminalCore`.
Supersedes #7508
References #395 (overall bracketed paste support request)
Tests added. Manually tested.
This adds the skeleton code for "bracketed paste mode" to the Windows
Terminal. No actual functionality is implemented yet, just the wiring
for handling DECSET/DECRST 2004.
References #395
Supersedes #7508
<!-- 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 implement the OSC 9;9
|Sequence|Descriptoin|
| :------------- | :----------: |
|ESC ] 9 ; 9 ; “cwd” ST | Inform ConEmu about shell current working directory.|
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#8214
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] Closes#8166
* [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] 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.
* [ ] 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
<!-- 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
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
* Add a tabColor parameter to the `new-tab` and `split-panes` command
* Add --tabColor to the command line, to allow bootstrapping with tabs
of different colors
Add another field to NewTerminalArgs. Use this field to set
StartingTabColor in Terminal. This color gets overridden by the color
defined by the profile / VT, however can be overridden with the color
picker.
Since the color is the property of the Terminal, when defined for the
tab this color is associated only with the first pane/terminal of the
tab. Additional panes will not inherit this color (to prevent advanced
resolution, where we need to resolve between the inherited color and the
one specified for the pane).
## Validation Steps Performed
* UT for parameters parsing
* Running system with several tabs of different colors.
* Adding custom actions with colors
* Performing operations like split pane, duplicate and so on
Closes#8075
This commit implements the OSC 9;4 sequence per the [ConEmu style].
| sequence | description |
| ------------ | ------------ |
| `ESC ] 9 ; 4 ; st ; pr ST` | Set progress state on taskbar and tab. |
| | When `st` is: |
| | |
| | `0`: remove progress. |
| | `1`: set progress value to `pr` (number, 0-100). |
| | `2`: set the taskbar to the "Error" state |
| | `3`: set the taskbar to the "Indeterminate" state |
| | `4`: set the taskbar to the "Warning" state |
We've also extended this with:
* st 3: set indeterminate state
* st 4: set paused state
We handle multiple tabs sending the sequence by using the the last focused
control's taskbar state/progress.
Upon receiving the sequence in `TerminalApi`, we send an event that gets caught
by `TerminalPage`. `TerminalPage` then fires another event that gets caught by
`AppHost` and that's where we set the taskbar progress.
Closes#3004
[ConEmu style]: https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
This pull request is the initial implementation of hyperlink auto
detection
Overall design:
- Upon startup, TerminalCore gives the TextBuffer some patterns it
should know about
- Whenever something in the viewport changes (i.e. text
output/scrolling), TerminalControl tells TerminalCore (through a
throttled function for performance) to retrieve the visible pattern
locations from the TextBuffer
- When the renderer encounters a region that is associated with a
pattern, it paints that region differently
References #5001Closes#574
This commit makes the Windows Terminal play an audible sound when the
`BEL` control character is output.
The `BEL` control was already being forwarded through conpty, so it was
just a matter of hooking up the `WarningBell` dispatch method to
actually play a sound. I've used the `PlaySound` API to output the sound
configured for the "Critical Stop" system event (aka _SystemHand_),
since that is the sound used in conhost.
## Validation
I've manually confirmed that the terminal produces the expected sound
when executing `echo ^G` in a cmd shell, or `printf "\a"` in a WSL bash
shell.
References:
* There is a separate issue (#1608) to deal with configuring the `BEL`
to trigger visual forms of notification.
* There is also an issue (#2360) requesting an option to disable the
`BEL`.
Closes#4046
This PR adds support for the _blink_ graphic rendition attribute. When a
character is output with this attribute set, it "blinks" at a regular
interval, by cycling its color between the normal rendition and a dimmer
shade of that color.
The majority of the blinking mechanism is encapsulated in a new
`BlinkingState` class, which is shared between the Terminal and Conhost
implementations. This class keeps track of the position in the blinking
cycle, which determines whether characters are rendered as normal or
faint.
In Windows Terminal, the state is stored in the `Terminal` class, and in
Conhost it's stored in the `CONSOLE_INFORMATION` class. In both cases,
the `IsBlinkingFaint` method is used to determine the current blinking
rendition, and that is passed on as a parameter to the
`TextAttribute::CalculateRgbColors` method when these classes are
looking up attribute colors.
Prior to calculating the colors, the current attribute is also passed to
the `RecordBlinkingUsage` method, which keeps track of whether there are
actually any blink attributes in use. This is used to determine whether
the screen needs to be refreshed when the blinking cycle toggles between
the normal and faint renditions.
The refresh itself is handled by the `ToggleBlinkingRendition` method,
which is triggered by a timer. In Conhost this is just piggybacking on
the existing cursor blink timer, but in Windows Terminal it needs to
have its own separate timer, since the cursor timer is reset whenever a
key is pressed, which is not something we want for attribute blinking.
Although the `ToggleBlinkingRendition` is called at the same rate as the
cursor blinking, we actually only want the cells to blink at half that
frequency. We thus have a counter that cycles through four phases, and
blinking is rendered as faint for two of those four. Then every two
cycles - when the state changes - a redraw is triggered, but only if
there are actually blinking attributes in use (as previously recorded).
As mentioned earlier, the blinking frequency is based on the cursor
blink rate, so that means it'll automatically be disabled if a user has
set their cursor blink rate to none. It can also be disabled by turning
off the _Show animations in Windows_ option. In Conhost these settings
take effect immediately, but in Windows Terminal they only apply when a
new tab is opened.
This PR also adds partial support for the `SGR 6` _rapid blink_
attribute. This is not used by DEC terminals, but was defined in the
ECMA/ANSI standards. It's not widely supported, but many terminals just
it implement it as an alias for the regular `SGR 5` blink attribute, so
that's what I've done here too.
## Validation Steps Performed
I've checked the _Graphic rendition test pattern_ in Vttest, and
compared our representation of the blink attribute to that of an actual
DEC VT220 terminal as seen on [YouTube]. With the right color scheme
it's a reasonably close match.
[YouTube]: https://www.youtube.com/watch?v=03Pz5AmxbE4&t=1m55sCloses#7388
- Render hyperlinks with a dashed underline
- Render hovered hyperlinks with a solid underline
- Show URI tooltip on hover
TermControl now has a canvas that contains a tiny border to which a
tooltip is attached. When we hover over hyperlinked text, we move the
border to the mouse location and update the tooltip content with the
URI.
Introduced a new underline type (HyperlinkUnderline), supports rendering
for it, and uses it to render hyperlinks. HyperlinkUnderline is usually
a dashed underline, but when a link is hovered, all text with the same
hyperlink ID is rendered with a solid underline.
References #5001
This PR is about the behavior of DECSCUSR. This PR changes the meaning
of DECSCUSR 0 to restore the cursor style back to user default. This
differs from what VT spec says but it’s used in popular terminal
emulators like iTerm2 and VTE-based ones. See #1604.
Another change is that for parameter greater than 6, DECSCUSR should be
ignored, instead of restoring the cursor to legacy. This PR fixes it.
See #7382.
Fixes#1604.
<!-- 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
Conhost can now support OSC8 sequences (as specified [here](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)). Terminal also supports those sequences and additionally hyperlinks can be opened by Ctrl+LeftClicking on them.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#204
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] Closes#204
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] 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.
* [ ] 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
<!-- 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
Added support to:
- parse OSC8 sequences and extract URIs from them (conhost and terminal)
- add hyperlink uri data to textbuffer/screeninformation, associated with a hyperlink id (conhost and terminal)
- attach hyperlink ids to text to allow for uri extraction from the textbuffer/screeninformation (conhost and terminal)
- process ctrl+leftclick to open a hyperlink in the clicked region if present
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Open up a PowerShell tab and type
```PowerShell
${ESC}=[char]27
Write-Host "${ESC}]8;;https://github.com/microsoft/terminal${ESC}\This is a link!${ESC}]8;;${ESC}\"
```
Ctrl+LeftClick on the link correctly brings you to the terminal page on github
![hyperlink](https://user-images.githubusercontent.com/26824113/89953536-45a6f580-dbfd-11ea-8e0d-8a3cd25c634a.gif)
MouseInput was directly asking user32 about the state of the mouse buttons,
which was somewhat of a layering violation. This commit makes all callers
have to pass the mouse state in themselves.
Closes#4869
This PR adds support for per-profile tab colors, in accordance with
#7134. This adds a single `tabColor` property, that when set, specifies
the background color for profile's tab. This color can be overridden by
the color picker, and clearing the color with the color picker will
revert to this default color set for the tab.
* Full theming is covered in #3327 & #5772
Validation: Played with setting this color, both on launch and via
hot-reload
Specified in #7134Closes#1337
## 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.
This is a refactoring of the renderer color calculations to simplify the
implementation, and to make it easier to support additional
color-altering rendition attributes in the future (e.g. _faint_ and
_conceal_).
## References
* This is a followup to PRs #3817 and #6809, which introduced additional
complexity in the color calculations, and which suggested the need for
refactoring.
## Detailed Description of the Pull Request / Additional comments
When we added support for `DECSCNM`, that required the foreground and
background color lookup methods to be able to return the opposite of
what was requested when the reversed mode was set. That made those
methods unnecessarily complicated, and I thought we could simplify them
considerably just by combining the calculations into a single method
that derived both colors at the same time.
And since both conhost and Windows Terminal needed to perform the same
calculations, it also made sense to move that functionality into the
`TextAttribute` class, where it could easily be shared.
In general this way of doing things is a bit more efficient. However, it
does result in some unnecessary work when only one of the colors is
required, as is the case for the gridline painter. So to make that less
of an issue, I've reordered the gridline code a bit so it at least
avoids looking up the colors when no gridlines are needed.
## Validation Steps Performed
Because of the API changes, quite a lot of the unit tests had to be
updated. For example instead of verifying colors with two separate calls
to `LookupForegroundColor` and `LookupBackgroundColor`, that's now
achieved with a single `LookupAttributeColors` call, comparing against a
pair of values. The specifics of the tests haven't changed though, and
they're all still working as expected.
I've also manually confirmed that the various color sequences and
rendition attributes are rendering correctly with the new refactoring.
## Summary of the Pull Request
This PR adds full support for the `DECSCNM` reverse screen mode in the Windows Terminal to align with the implementation in conhost.
## References
* The conhost implementation of `DECSCNM` was in PR #3817.
* WT originally inherited that functionality via the colors being passed through, but that behaviour was lost in PR #6506.
## PR Checklist
* [x] Closes#6622
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] 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.
* [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: #6622
## Detailed Description of the Pull Request / Additional comments
The `AdaptDispatch::SetScreenMode` now checks if it's in conpty mode and simply returns false to force a pass-through of the mode change. And the `TerminalDispatch` now has its own `SetScreenMode` implementation that tracks any changes to the reversed state, and triggers a redraw in the renderer.
To make the renderer work, we just needed to update the `GetForegroundColor` and `GetBackgroundColor` methods of the terminal's `IRenderData` implementation to check the reversed state, and switch the colors being calculated, the same way the `LookupForegroundColor` and `LookupBackgroundColor` methods work in the conhost `Settings` class.
## Validation Steps Performed
I've manually tested the `DECSCNM` functionality for Windows Terminal in Vttest, and also with some of my own test scripts.
This is essentially a rewrite of the
`TerminalDispatch::SetGraphicsRendition` method, bringing it into closer
alignment with the `AdaptDispatch` implementation, simplifying the
`ITerminalApi` interface, and making the code easier to extend. It adds
support for a number of attributes which weren't previously implemented.
REFERENCES
* This is a mirror of the `AdaptDispatch` refactoring in PR #5758.
* The closer alignment with `AdaptDispatch` is a small step towards
solving issue #3849.
* The newly supported attributes should help a little with issues #5461
(italics) and #6205 (strike-through).
DETAILS
I've literally copied and pasted the `SetGraphicsRendition`
implementation from `AdaptDispatch` into `TerminalDispatch`, with only
few minor changes:
* The `SetTextAttribute` and `GetTextAttribute` calls are slightly
different in the `TerminalDispatch` version, since they don't return a
pointless `success` value, and in the case of the getter, the
`TextAttribute` is returned directly instead of by reference.
Ultimately I'd like to move the `AdaptDispatch` code towards that way
of doing things too, but I'd like to deal with that later as part of a
wider refactoring of the `ConGetSet` interface.
* The `SetIndexedForeground256` and `SetIndexedBackground256` calls
required the color indices to be remapped in the `AdaptDispatch`
implementation, because the conhost color table is in a different
order to the XTerm standard. `TerminalDispatch` doesn't have that
problem, so doesn't require the mapping.
* The index color constants used in the 16-color `SetIndexedForeground`
and `SetIndexedBackground` calls are also slightly different for the
same reason.
VALIDATION
I cherry-picked this code on top of the #6506 and #6698 PRs, since
that's only way to really get the different color formats passed-through
to the terminal. I then ran a bunch of manual tests with various color
coverage scripts that I have, and confirmed that all the different color
formats were being rendered as expected.
Closes#6725
With this commit, terminal will be able to copy text to the system
clipboard by using OSC 52 MANIPULATE SELECTION DAATA.
We chose not to implement the clipboard querying functionality offered
by OSC 52, as sending the clipboard text to an application without the
user's knowledge or consent is an immense security hole.
We do not currently support the clipboard specifier Pc to specify which
clipboard buffer should be filled
# Base64 encoded `foo`
$ echo -en "\e]52;;Zm9v\a"
# Multiple lines
# Base64 encoded `foo\r\nbar`
$ echo -en "\e]52;;Zm9vDQpiYXI=\a"
Closes#2946.
This pull request implements shift+double/triple click. Proper behavior
(as described in #4557) is to only expand one selection point, not both.
Adding the `bool targetStart` was a bit weird. I decided on this being
the cleanest approach though because I still want `PivotSelection` to be
its own helper function. Otherwise, the concept of "pivoting" gets kinda
messy.
## Validation Steps Performed
Manual testing as described on attached issue.
Tests were added for Shift+Click and pivoting the selection too.
Closes#4557
In addition to the below (original) description, this commit introduces
a ThrottledFunc template that can throttle _any_ function. It applies
that type to muffle updates to the scrollbar.
---
Redo #3531 but without the bug that it caused (#3622) which is why it
was reverted.
I'm sorry if I explain this badly. If you don't understand a part, make
sure to let me know and I will explain it better.
### Explanation
How it worked before: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it dispatches work for later to be ran the UI thread
to updates the scrollbar's values
Why it's bad:
* If we have many viewport changes, it will create a long stack of
operations to run. Instead, we should just update the scroll bar with
the most recent information that we know.
* Imagine if the rate that the work gets pushed on the UI thread is
greater than the rate that it can handle: it might freeze?
* No need to be real time, we can wait just a little bit (8ms) to
accumulate viewport changes before we actually change the scroll bar's
value because it appears to be expensive (see perf below).
Now: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it tells the `ScrollBarUpdater` about a new update ->
the `ScrollBarUpdater` only runs one job (I don't know if that's the
right term) on the UI thread at a time. If a job is already running but
hasn't updated the scroll bar yet, it changes the setting in the already
existing job to update the scroll bar with the new values. A job "waits"
some time before doing the update to throttle updates because we don't
need real time scroll bar updates. -> eventually, it updates the scroll
bar If the user scrolls when a scroll bar update is pending, we keep the
scroll bar's Maximum and Minimum but let the user choose its new Value
with the `CancelPendingValueChange` method.
### Note
Also I changed a little bit the code from the Terminal to notify the
TermControl less often when possible.
I tried to scroll with the scroll bar, with the mouse wheel. I tried to
scroll while content is being outputted.
I tried to reproduce the crash from #2248 without success (good).
Co-authored-by: Leonard Hecker <leonard@hecker.io>
Closes#3622
When opening a new tab, it takes a few milliseconds before title to
appears. This PR makes it instantaneous.
* Updated the Terminal so that it can load the title from the settings
before it is initialized.
* Load terminal settings in TermControl constructor before the terminal
is initialized (see above).
* Update Tab so that it sets the TabViewItem's title in the constructor
(in Tab::_MakeTabViewItem) instead of waiting for the VT sequence to
set the title (from what I understand).
NOTE 1: there is a similar problem with the tabview icon which is not
fixed by this PR.
NOTE 2: This is only a problem with animations disabled because
otherwise the title fades in so there is enough time for it to be set
when it becomes visible.
## Validation
I ran the terminal and opened a new tab. The title appears instantly.
Adds support for `win32-input-mode` to conhost, conpty, and the Windows
Terminal.
* The shared `terminalInput` class supports sending these sequences when
a VT client application requests this mode.
* ConPTY supports synthesizing `INPUT_RECORD`s from the input sent to it
from a terminal
* ConPTY requests this mode immediately on startup (if started with a
new flag, `PSEUDOCONSOLE_WIN32_INPUT_MODE`)
* The Terminal now supports sending this input as well, when conpty asks
for it.
Also adds a new ConPTY flag `PSEUDOCONSOLE_WIN32_INPUT_MODE` which
requests this functionality from conpty, and the Terminal requests this
by default.
Also adds `experimental.input.forceVT` as a global setting to let a user
opt-out of this behavior, if they don't want it / this ends up breaking
horribly.
## Validation Steps Performed
* played with this mode in vtpipeterm
* played with this mode in Terminal
* checked a bunch of scenarios, as outlined in a [comment] on #4999
[comment]: https://github.com/microsoft/terminal/issues/4999#issuecomment-628718631
References #4999: The megathread
References #5887: The spec
Closes#879Closes#2865Closes#530Closes#3079Closes#1119Closes#1694Closes#3608Closes#4334Closes#4446
## Summary of the Pull Request
Some people wish to use Ctrl+Alt combinations without Windows treating those as an alias for AltGr combinations. This PR adds a new `altGrAliasing` setting allowing one to control this behavior.
## PR Checklist
* [x] Closes#6211
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Manual testing
* [x] Requires documentation to be updated: https://github.com/MicrosoftDocs/terminal/issues/50
* [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
* Choose a German keyboard layout
* Using `showkey -a` ensured that both `Ctrl+Alt+Q/E` and `AltGr+Q/E` produce `@/€`
* Added `"altGrAliasing": false` to the WSL profile
* Using `showkey -a` ensured `Ctrl+Alt+Q/E` now produces `^[^Q/E` while `AltGr+Q/E` continues to produce `@/€`
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes#1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
This pull request moves swaths of Cascadia to use `til::color` for color
interop. There are still some places where we use `COLORREF`, such as in
the ABI boundaries between WinRT components.
I've also added two more til::color helpers - `with_alpha`, which takes
an existing color and sets its alpha component, and a
`Windows::UI::Color` convertor pair.
Future direction might include a `TerminalSettings::Color` type at the
idl boundary so we can finally stop using UInt32s (!) for color.
## Validation Steps Performed
Tested certain fragile areas:
* [x] setting the background with OSC 11
* [x] setting the background when acrylic is in use (which requires
low-alpha)
## Summary of the Pull Request
This PR clamp the "new rows" scrolling value to a positive number. We can't create a negative number of new rows. It also adds a test.
## References
## PR Checklist
* [x] Closes#5540
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
The origin of this bug is that as newlines are emitted, we'll accumulate an enormous scroll delta into a selection region, to the point of overflowing a `SHORT`. When the overflow occurs, the `Terminal` would fail to send a `NotifyScroll()` to the `TermControl` hosting it.
For this bug to repro, we need to:
- Have a sufficiently large buffer, because each newline we'll accumulate a delta of (0, ~bufferHeight), so (bufferHeight^2 + bufferHeight) > SHRT_MAX
- Have a selection
## Validation Steps Performed
* Dustin verified this actually
* Created a new insane test case
# Summary of the Pull Request
This PR will allow the cursor to be double width when on top of a double width character. This required changing `IsCursorDoubleWidth` to check whether the glyph the cursor's on top of is double width. This code is exactly the same as the original PR that addressed this issue in #2932. That one got reverted at some point due to the crashes related to it, but due to a combination of Terminal having come further since that PR and other changes to address use-after-frees, some of the crashes may/may not be relevant now. The ones that seemed to be relevant/repro-able, I attempt to address in this PR.
The `IsCursorDoubleWidth` check would fail during the `TextBuffer::Reflow` call inside of `Terminal::UserResize` occasionally, particularly when `newCursor.EndDeferDrawing()` is called. This is because when we tell the newCursor to `EndDefer`, the renderer will attempt to redraw the cursor. As part of this redraw, it'll ask if `IsCursorDoubleWidth`, and if the renderer managed to ask this before `UserResize` swapped out the old buffer with the new one from `Reflow`, the renderer will be asking the old buffer if its out-of-bounds cursor is double width. This was pretty easily repro'd using `cmatrix -u0` and resizing the window like a madman.
As a solution, I've moved the Start/End DeferDrawing calls out of `Reflow` and into `UserResize`. This way, I can "clamp" the portion of the code where the newBuffer is getting created and reflowed and swapped into the Terminal buffer, and only allow the renderer to draw once the swap is done. This also means that ConHost's `ResizeWithReflow` needed to change slightly.
In addition, I've added a WriteLock to `SetCursorOn`. It was mentioned as a fix for a crash in #2965 (although I can't repro), and I also figured it would be good to try to emulate where ConHost locks with regards to Cursor operations, and this seemed to be one that we were missing.
## PR Checklist
* [x] Closes#2713
* [x] CLA signed
* [x] Tests added/passed
## Validation Steps Performed
Manual validation that the cursor is indeed chonky, added a test case to check that we are correctly saying that the cursor is double width (not too sure if I put it in the right place). Also open to other test case ideas and thoughts on what else I should be careful for since I am quite nervous about what other crashes might occur.
My basic idea was that `WM_CHAR` is just the better `WM_KEYDOWN`.
The latter fails to properly support common dead key sequences like in
#3516.
As such I added some logic to `Terminal::SendKeyEvent` to make it return
false if the pressed key represents a printable character.
This causes us to receive a character event with a (hopefully) correctly
composed code unit, which then gets sent to `Terminal::SendCharEvent`.
`Terminal::SendCharEvent` in turn had to be modified to support
potentially pressed modifier keys, since `Terminal::SendKeyEvent` isn't
doing that for us anymore.
Lastly `TerminalInput` had to be modified heavily to support character
events with modifier key states. In order to do so I merged its
`HandleKey` and `HandleChar` methods into a single one, that now handles
both cases.
Since key events will now contain character data and character events
key codes the decision logic in `TerminalInput::HandleKey` had to be
rewritten.
## PR Checklist
* [x] CLA signed
* [x] Tests added/passed
* [x] I've discussed this with core contributors already.
## Validation Steps Performed
* See #3516.
* I don't have any keyboard that generates surrogate characters. Due to
this I modified `TermControl::_SendPastedTextToConnection` to send the
data to `_terminal->SendCharEvent()` instead. I then pasted the test
string ""𐐌𐐜𐐬" and ensured that the new `TerminalInput::_SendChar`
method still correctly assembles surrogate pairs.
Closes#3516Closes#3554 (obsoleted by this PR)
Potentially impacts #391, which sounds like a duplicate of #3516
<!-- 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 will allow TSFInputControl to redraw its Canvas and TextBlock in response to when the Terminal cursor position updates. This will fix the issue where during Korean composition, the first symbol of the next composition will appear on top of the previous composed character. Since the Terminal Cursor updates a lot, I've added some checks to see if the TSFInputControl really needs to redraw. This will also decrease the number of actual redraws since we receive a bunch of `LayoutRequested` events when there's no difference between them.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#4963
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Startup, teardown, CJK IME gibberish testing, making sure the IME block shows up in the right place.
This commit rewrites selection handling at the TermControl layer.
Previously, we were keeping track of a number of redundant variables
that were easy to get out of sync.
The new selection model is as follows:
* A single left click will always begin a _pending_ selection operation
* A single left click will always clear a selection (#4477)
* A double left click will always begin a word selection
* A triple left click will always begin a line selection
* A selection will only truly start when the cursor moves a quarter of
the smallest dimension of a cell (usually its width) in any direction
_This eliminates the selection of a single cell on one click._
(#4282, #5082)
* We now keep track of whether the selection has been "copied", or
"updated" since it was last copied. If an endpoint moves, it is
updated. For copy-on-select, it is only copied if it's updated.
(#4740)
Because of this, we can stop tracking the position of the focus-raising
click, and whether it was part of click-drag operation. All clicks can
_become_ part of a click-drag operation if the user drags.
We can also eliminate the special handling of single cell selection at
the TerminalCore layer: since TermControl determines when to begin a
selection, TerminalCore no longer needs to know whether copy on select
is enabled _or_ whether the user has started and then backtracked over a
single cell. This is now implicit in TermControl.
Fixes#5082; Fixes#4477
This commit introduces a github action to check our spelling and fixes
the following misspelled words so that we come up green.
It also renames TfEditSes to TfEditSession, because Ses is not a word.
currently, excerpt, fallthrough, identified, occurred, propagate,
provided, rendered, resetting, separate, succeeded, successfully,
terminal, transferred, adheres, breaks, combining, preceded,
architecture, populated, previous, setter, visible, window, within,
appxmanifest, hyphen, control, offset, powerpoint, suppress, parsing,
prioritized, aforementioned, check in, build, filling, indices, layout,
mapping, trying, scroll, terabyte, vetoes, viewport, whose