`ProcessString` may delete the ASB and cause a dangling screen info
pointer. As such, we must avoid using the pointer after the call.
Closes#17709
## Validation Steps Performed
I couldn't repro the issue.
* Adds a check whether the thread dispatcher is already null.
(See code comments.)
* Moves the `_settings` to only happen on the UI thread.
Anything else wouldn't be thread safe.
Closes#17620
## Validation Steps Performed
Not reproducible. 🚫
Once all applications that have received a `WM_ENDSESSION` message
have returned from processing said message, windows will terminate
all processes. This forces us to process the message synchronously.
This meant that this issue was timing dependent. If Windows Terminal
was quick at persisting buffers and you had some other application that
was slow to shut down (e.g. Steam), you would never see this issue.
Closes#17179Closes#17250
## Validation Steps Performed
* Set up a lean Hyper-V VM for fast reboots
* `Set-VMComPort <vm> 1 \\.pipe\\<pipe>`
* Hook up WIL to write to COM1
* Add a ton of debug prints all over the place
* Read COM output with Putty for hours
* RTFM, and notice that the `WM_ENDSESSION` documentation states
"the session can end any time after all applications
have returned from processing this message"
* Be very very sad ✅
* Fix it
* Rebooting now shows on COM1 that persistence runs ✅
* Windows get restored after reboot ✅
## Summary of the Pull Request
When conhost receives input from a conpty connection, and that input
arrives in a block larger than our 4K buffer, we can end up with a VT
sequence that's split at the buffer boundary. Previously that could
result in the start of the sequence being dropped, and the remaining
characters being interpreted as individual key presses.
This PR attempts to fix the issue by caching the unprocessed characters
from the start of the sequence, and then combining them with the second
half of the sequence when it's later received.
## Validation Steps Performed
I've confirmed that pasting into vim now works correctly with the sample
data from issue #16655. I've also tested with a `DECCTR` report larger
than 4K which would previously have been corrupted, and which now works
as expected.
## PR Checklist
- [x] Closes#16655
With the merge of #17638, selections are now accumulated early in the
rendering process. This allows Atlas, which currently makes decisions
about cell foreground/background at the time of text rendering,
awareness of the selection ranges *before* text rendering begins.
As a result, we can now paint the selection into the background and
foreground bitmaps. We no longer need to overlay a rectangle, or series
of rectangles, on top of the rendering surface and alpha blend the
selection color onto the final image.
As a reminder, "alpha selection" was always a stopgap because we didn't
have durable per-cell foreground and background customization in the
original DxEngine.
Selection foregrounds are not customizable, and will be chosen using the
same color distancing algorithm as the cursor. We can make them
customizable "easily" (once we figure out the schema for it) for #3580.
`ATLAS_DEBUG_SHOW_DIRTY` was using the `Selection` shading type to draw
colored regions. I didn't want to break that, so I elected to rename the
`Selection` shading type to `FilledRect` and keep its value. It helps
that the shader didn't have any special treatment for
`SHADING_TYPE_SELECTION`.
This fixes the entire category of issues created by selection being an
80%-opacity white rectangle. However, given that it changes the imputed
colors of the text it will reveal `SGR 8` concealed/hidden characters.
Refs #17355
Refs #14859
Refs #11181
Refs #8716
Refs #4971Closes#3561
Now that the store displays changelogs, it seems unfair for us to not
put something in here.
These are intended to give a rough idea, not to be perfect, as they are
not the product of my hours of changelog writing (since I am lazy and
put that off until the day of release 🫣)
When we have a series of image slices of differing widths, which also
don't align with the cell boundaries, we can get rounding errors in the
scaling which makes the different slices appear misaligned.
This PR fixes the issue by removing the 4 pixel width alignment that was
enforced in the `ImageSlice` class, since that's not actually necessary
when the pixels themselves are already 4 bytes in size. And without
that, the widths should be correctly aligned with the cell boundaries.
## References and Relevant Issues
The initial Sixel implementation was added in PR #17421.
## Validation Steps Performed
I've confirmed that this fixes the rendering glitches reported in
#17711, and all my existing Sixel tests still work as expected.
Closes#17711
`HSTRING` does not permit strings that aren't null-terminated.
As such we'll simply use a plain char array which compiles down to
a `UINT32` and `wchar_t*` pointer pair. Unfortunately, cppwinrt uses
`char16_t` in place of `wchar_t`, and also offers no trivial conversion
between `winrt::array_view` and `std::wstring_view` either.
As such, most of this PR is about explicit type casting.
Closes#17697
## Validation Steps Performed
* Patch the `DeviceAttributes` implementation in `adaptDispatch.cpp`
to respond like this:
```cpp
_api.ReturnResponse({L"ABCD", 3});
```
* Open a WSL shell and execute this:
```sh
printf "\e[c"; read
```
* Doesn't crash ✅
This PR introduces the framework for the `DECRQTSR` sequence which is
used to query terminal state reports. But for now I've just implemented
the `DECCTR` color table report, which provides a way for applications
to query the terminal's color scheme.
## References and Relevant Issues
This is the counterpart to the the `DECRSTS` sequence, which is used to
restore a color table report. That was implemented in PR #13139, but it
only became practical to report the color table once conpty passthrough
was added in PR #17510.
## Detailed Description of the Pull Request / Additional comments
This sequence has the option of reporting the colors as either HLS or
RGB, but in both cases the resolution is lower than 24 bits, so the
colors won't necessarily round-trip exactly when saving and restoring.
The HLS model in particular can accumulate rounding errors over time.
## Validation Steps Performed
I've added a basic unit test that confirms the colors are reported as
expected for both color models. The color values in these tests were
obtained from color reports on a real VT525 terminal.
## PR Checklist
- [x] Tests added/passed
We got some new icons for Developer Command Prompt and Developer
PowerShell from our friends over on Visual Studio!
This pull request includes them in the package, and fixes up the VS
dynamic profiles to reset any icons that matched the old paths.
This may be a minor breaking change for user settings, but we're making
the assumption that if they didn't change their VS profile icons from
the defaults, they probably want to follow us to the new defaults.
To prevent anything like this from happening again, we're going to stop
serializing icons for stub profiles.
I've also included a VS version of the PowerShell "black" icon which is
currently unused, but can be used in the future for PS7+-based VS Dev
Shell.
Closes#17627
`RealUnicodeToFalseUnicode` was described as:
> This routine converts a unicode string into the correct characters
> for an OEM (cp 437) font. This code is needed because the gdi glyph
> mapper converts unicode to ansi using codepage 1252 to index font.
> This is how the data is stored internally.
In other words, it takes a UCS2 string, translates it to the current
codepage and translates it back to UCS2 in the US version of Windows.
In the "eastern" DBCS version it "reinterprets" the DBCS string as
`CP_USA` (a particularly weird quirk).
The original implementation used to do this translation at every
opportunity where text went into or out of conhost.
The translation was weird, but it was consistent.
In Windows 10 RS1 conhost got a new UCS2-aware text buffer and
this translation was removed from most places, as the text buffer
was converted to store proper UCS2. This broke the entire concept
of the translation though. Whatever data you previously wrote with
something like `WriteConsoleOutputCharacter` now came back with
something entirely else via `ReadConsoleOutput`.
In other words, I believe past RS1 there was technically never any
point in "munging" `CHAR_INFO`s, as this only covered 2 API functions.
Still, this does mean that this PR represents an API breaking change.
It's a minor one though, because it only affects 2 API functions.
And more importantly, it's a necessary breaking change as we move
further and further away from correlating codepoint and column counts.
## Validation Steps Performed
* Remaining tests pass ✅
This removes the `Terminal::SetViewportPosition` call from session
restoration which was responsible for putting the viewport below
the buffer height and caused the renderer to fail.
In order to prevent such issues in the future, `SetViewportPosition`
now protects itself against out of bounds requests.
Closes#17639
## Validation Steps Performed
* Enable persistence
* Print `big.txt`
* Restart
* Looks good ✅
In #17638, I am moving selection to an earlier phase of rendering (so
that further phases can take it into account). Since I am drafting off
the design of search highlights, one of the required changes is moving
to passing `span`s of `point_span`s around to make selection effectively
zero-copy.
We can't easily have zero-copy selection propagation without caching,
and we can't have caching without mandatory cache invalidation.
This pull request moves both conhost and Terminal to use
`til::generational` for all selection members that impact the ranges
that would be produced from `GetSelectionRects`.
This required a move from `std::optional<>` to a boolean to determine
whether a selection was active in Terminal.
We will no longer regenerate the selection rects from the selection
anchors plus the text buffer *every single frame*.
Apart from being annoying to read, there is one downside.
If you begin a selection on a narrow character, _and that narrow
character later turns into a wide character_, we will show it as
half-selected.
This should be a rare-enough case that we can accept it as a regression.
This simplifies the code (from the perspective of the CPU) by doing
some miniscule-feels-good optimizations like replacing `snprintf` with
regular string concatenation and by doing an actual optimization by
removing the remaining calls to the WinRT `ApplicationModel` namespace.
More importantly however it fixes a bug: The only reason `elevate-shim`
worked at all is because the shell extension passed "wrong" parameters
to `CreateProcess`. Instead of repeating the application path in the
command line argument again, as is convention in C and on Windows, and
getting the 2nd and following parameters as an argument to `wWinMain`,
it used `GetCommandLineW` to get the original, broken command line.
This fixes the issue by passing the application path as the first
argument, which allows `elevate-shim` to be called like any other app.
## Validation Steps Performed
* Deploy WT and restart explorer
* Clicking "Open in Terminal (Dev)" works ✅
* Clicking "Open in Terminal (Dev)" while holding Ctrl+Shift
opens WT as admin ✅
The only reason we had the `SetTextAttributes` method in `ITerminalApi`
was to allow for conhost to remap the default color attributes when the
VT PowerShell quirk was active. Since that quirk has now been removed,
there's no need for this API anymore.
## References and Relevant Issues
The PowerShell quirk was removed in PR #17666.
## Validation Steps Performed
I've had to update all the attribute tests in adapterTest to manually
check the expected attributes, since those checks were previously being
handled in a `SetTextAttributes` mock which no longer exists.
I've also performed some manual tests of the VT attribute operations to
double check that they're still working as expected.
Between fmt 7.1.3 and 11.0.2 a lot has happened. `wchar_t` support is
now more limited and implicit conversions don't work anymore.
Furthermore, even the non-`FMT_COMPILE` API is now compile-time checked
and so it fails to work in our UI code which passes `hstring` format
strings which aren't implicitly convertible to the expected type.
`fmt::runtime` was introduced for this but it also fails to work for
`hstring` parameters. To solve this, a new `RS_fmt` macro was added
to abstract the added `std::wstring_view` casting away.
Finally, some additional changes to reduce `stringstream` usage
have been made, whenever `format_to`, etc., is available.
This mostly affects `ActionArgs.cpp`.
Closes#16000
## Validation Steps Performed
* Compiles ✅
* Settings page opens ✅
This sends a telemetry event if a session is interacted with.
Specifically, key events are essential to have an interactive session in
Windows Terminal, so we're tracking sessions that have had a key down
event.
The answerback feature allows for the user to define a message that the
terminal will transmit to the host whenever an `ENQ` (enquiry) control
character is received.
## Detailed Description of the Pull Request / Additional comments
In Windows Terminal, the message can be configured at the profile level
of the settings file, as a string property named `AnswerbackMessage`.
In ConHost, the message can be configured in the registry, again as a
string value with the name `AnswerbackMessage`.
## Validation Steps Performed
I've confirmed that the control is working as intended in both Windows
Terminal and ConHost using Vttest.
Closes#11946
In several places the old conhost codebase appears to assume that any
wide glyph is represented by two codepoints. This is probably an
artifact of the ASCII/DBCS split that conhost used to have.
When conhost got merged into a single UCS2-aware application,
this artifact was apparently never properly resolved.
To my knowledge there are at least two places where this assumption
exists: The clipboard code which translates non-wide non-ascii
characters to Alt-numpad sequences, and this code. Both are wrong.
This is because in a Unicode-context there's no correlation between
the number of codepoints and the width of the glyph, even with UCS2.
In a post-UCS2-world the correct check is for surrogate pairs,
as they must be avoided for the same reason DBCS were avoided.
One could consider this a breaking change of the API,
as this can now result in repeat counts >1 for wide glyphs.
If someone complained about this change in behavior, I'd probably
not change it back, as narrow complex Unicode characters exist too.
This delays the CSI J until we know the new origin of the prompt.
That way it's at the right (reflowed) position.
## Validation Steps Performed
* conhost
* Print a ton of text
* Write a prompt of a hundred chars
* Resize the window very narrow / wide
* Works ✅
* Windows Terminal
* Write a prompt of a hundred chars
* Resize the window very narrow / wide
* Works ✅
This adds an indirection for `_KeyHandler` so that `OnDirectKeyEvent`
can call `_KeyHandler`. This allows us to consistently handle
Alt-key-up events. Then I added custom handling for Alt+ddd (OEM),
Alt+0ddd (ANSI), and Alt+'+'+xxxx (Unicode) sequences, due to the
absence of Alt-key events with xaml islands and our TSF control.
Closes#17327
## Validation Steps Performed
* Tested it according to https://conemu.github.io/en/AltNumpad.html
* Unbind Alt+Space
* Run `showkey -a`
* Alt+Space generates `^[ `
* F7 generates `^[[18~`
## Summary of the Pull Request
Adds a scroll offset to avoid hiding the current search highlight with
the search box.
- Offset is based on the number of rows that the search box takes up.
(I am not totally sure I am calculating this right)
- This won't help when the current highlight is in the first couple
rows of the buffer.
Fixes: #4407
* Added/changed comments as mentioned.
* Improved the ugly `resize_and_overwrite` hack into the STL.
* Add `Write` functions for xterm's window API.
* The only reason we needed a move operator for `VtIo::Writer`
is because we used it in a ternary in `CONSOLE_INFORMATION`.
Ternaries are like if branches with hidden move assignments.
Instead, we simply construct each `Writer` in place.
No ternary = No move = No problems in life.
The best benefit of this is that this makes calling `GetVtWriter`
a hundred times cheaper.
Otherwise, I still need to extend a few tests in `VtIoTests`,
but I'm planning to do that later.
* Every single place that called `read_file_as_utf8_string_if_exists`
would immediately do a `.value_or(std::string{})`.
As such, the function now returns a string directly.
* There was just one caller to `read_file_as_utf8_string`
and it only cared about files that are non-empty.
As such, the specialization got removed.
Both of these make sense to me, as in practice there's seldom
a difference between an empty file and a non-existent one.
## Validation Steps Performed
* Compiles ✅
* Starts ✅
* Deleting the `settings.json` contents triggers a reload ✅
BackendD2D will now draw one extra cell on all sides when rendering the
background, filled with the expected background color, starting at (-1,
-1) to ensure that cell backgrounds do not bleed over the edges of the
viewport where the is swapchain but no content.
Fixes#17672
Roughly 4 years ago we gave Windows Terminal the ability to
differentiate between black/white and the default colors.
One of the victims was PowerShell and most importantly PSReadLine,
which emit SRG 37 & 40 when what they really want is 38 & 48.
We fixed this on our side by adding a shim.
Since the addition of VT passthrough in #17510 we now intentionally
lost the ability to translate VT sequences from one thing to another.
This meant we also lost the ability to do this shim and as such
this PR removes it. Luckily Windows 11 now ships PSReadLine 2.0.0,
which contains a proper fix for this.
Unfortunately, this is not the case for Windows 10, which ships
PSReadLine 2.0.0-beta2. Users affected by this will have to install
a newer version of PSReadLine or use the default black/white theme.
See 1bf4c082b4Closes#13037
This PR adds support for querying the cursor style - technically the
state of the `DECSCUSR` setting - using a `DECRQSS` escape sequence.
## References and Relevant Issues
The initial `DECRQSS` support was added in PR #11152, but it wasn't
practical to report the cursor style until conpty passthrough was added
in PR #17510.
## Detailed Description of the Pull Request / Additional comments
If the user has chosen a cursor style that isn't one of the shapes
supported by the `DECSCUSR` control, we report those as 0 (i.e. the
default style). That way, if an application later tries to restore the
cursor using the returned value, it should still be reset to its
original state.
I also took the opportunity in this PR to do some refactoring of the
other `DECRQSS` reports, since several of them were using unnecessary
appending that could be simplified to a single `fmt::format` call, or
even just static strings in some cases.
## Validation Steps Performed
I've checked the reports are working as expected in Vttest, and also
added some unit tests.
## PR Checklist
- [x] Tests added/passed
We aren't sure what exactly it is, but on the latest toolchain
this code miscompiles. The fmt call throws an exception because
it supposedly has too few arguments supplied for the format string.
Debugging the issue shows that the `next_arg_id_` internal to `fmt`
is 10000, even though it's parsing the first argument. At that point
it's supposed to be 0. This code hasn't been changed in years.
My hope is that this slight shuffling of the code causes
the issue to go away.
The idea is that we can translate Console API calls directly to VT at
least as well as the current VtEngine setup can. For instance, a call
to `SetConsoleCursorPosition` clearly translates directly to a `CUP`
escape sequence. Effectively, instead of translating output
asynchronously in the renderer thread, we'll do it synchronously
right during the Console API call.
Most importantly, the this means that any VT output that an
application generates will now be given to the terminal unmodified.
Aside from reducing our project's complexity quite a bit and opening
the path towards various interesting work like sixels, Device Control
Strings, buffer snapshotting, synchronized updates, and more, it also
improves performance for mixed text output like enwik8.txt in conhost
to 1.3-2x and in Windows Terminal via ConPTY to roughly 20x.
This adds support for overlapped IO, because now that output cannot
be "skipped" anymore (VtEngine worked like a renderer after all)
it's become crucial to block conhost as little as possible.
⚠️ Intentionally unresolved changes/quirks:
* To force a delayed EOL wrap to wrap, `WriteCharsLegacy` emits a
`\r\n` if necessary. This breaks text reflow on window resize.
We cannot emit ` \r` the way readline does it, because this would
overwrite the first column in the next row with a whitespace.
The alternative is to read back the affected cell from the buffer
and emit that character and its attributes followed by a `\r`.
I chose to not do that, because buffer read-back is lossy (= UCS2).
Unless the window is resized, the difference is unnoticeable
and historically, conhost had no support for buffer reflow anyway.
* If `ENABLE_VIRTUAL_TERMINAL_PROCESSING` is set while
`DISABLE_NEWLINE_AUTO_RETURN` is reset, we'll blindly replace all
LF with CRLF. This may hypothetically break DCS sequences, but it's
the only way to do this without parsing the given VT string and
thus the only way we can achieve passthrough mode in the future.
* `ENABLE_WRAP_AT_EOL_OUTPUT` is translated to `DECAWM`.
Between Windows XP and Windows 11 21H2, `ENABLE_WRAP_AT_EOL_OUTPUT`
being reset would cause the cursor position to reset to wherever
a write started, _if_ the write, including expanded control chars,
was less than 100 characters long. If it was longer than that,
the cursor position would end up in an effectively random position.
After lengthy research I believe that this is a bug introduced in
Windows XP and that the original intention was for this mode to be
equivalent to `DECAWM`. This is compounded by MSDN's description
(emphasis mine):
> If this mode is disabled, the **last character** in the row is
> overwritten with any subsequent characters.
⚠️ Unresolved issues/quirks:
* Focus/Unfocus events are injected into the output stream without
checking whether the VT output is currently in a ground state.
This may break whatever VT sequence is currently ongoing.
This is an existing issue.
* `VtIo::Writer::WriteInfos` should properly verify the width of
each individual character.
* Using `SetConsoleActiveScreenBuffer` destroys surrogate pairs
and extended (VT) attributes. It could be translated to VT pages
in the long term.
* Similarly, `ScrollConsoleScreenBuffer` results in the same and
could be translated to `DECCRA` and `DECFRA` in the near term.
This is important because otherwise `vim` output may loose
its extended attributes during scrolling.
* Reflowing a long line until it wraps results in the cooked read
prompt to be misaligned vertically.
* `SCREEN_INFORMATION::s_RemoveScreenBuffer` should trigger a
buffer switch similar to `SetConsoleActiveScreenBuffer`.
* Translation of `COMMON_LVB_GRID_HORIZONTAL` to `SGR 53` was dropped
and may be reintroduced alongside `UNDERSCORE` = `SGR 4`.
* Move the `OSC 0 ; P t BEL` sequence to `WriteWindowTitle`
and swap the `BEL` with the `ST` (`ESC \`).
* PowerShell on Windows 10 ships with PSReadLine 2.0.0-beta2
which emits SGR 37/40 instead of 39/49. This results in black
spaces when typing and there's no good way to fix that.
* A test is missing that ensures that `FillConsoleOutputCharacterW`
results in a `CSI n J` during the PowerShell shim.
* A test is missing that ensures that `PtySignal::ClearBuffer`
does not result in any VT being generated.
Closes#262Closes#1173Closes#3016Closes#4129Closes#5228Closes#8698Closes#12336Closes#15014Closes#15888Closes#16461Closes#16911Closes#17151Closes#17313