2019-05-03 00:29:04 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <conattrs.hpp>
|
|
|
|
|
Expose Text Attributes to UI Automation (#10336)
## 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
2021-07-10 01:21:35 +02:00
|
|
|
#include "../../inc/DefaultSettings.h"
|
2019-05-03 00:29:04 +02:00
|
|
|
#include "../../buffer/out/textBuffer.hpp"
|
2021-02-18 03:31:52 +01:00
|
|
|
#include "../../types/inc/sgrStack.hpp"
|
Add support for the "blink" graphic rendition attribute (#7490)
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=1m55s
Closes #7388
2020-09-22 01:21:33 +02:00
|
|
|
#include "../../renderer/inc/BlinkingState.hpp"
|
2019-05-03 00:29:04 +02:00
|
|
|
#include "../../terminal/parser/StateMachine.hpp"
|
|
|
|
#include "../../terminal/input/terminalInput.hpp"
|
|
|
|
|
|
|
|
#include "../../types/inc/Viewport.hpp"
|
Show a double width cursor for double width characters (#5319)
# 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.
2020-04-15 21:23:06 +02:00
|
|
|
#include "../../types/inc/GlyphWidth.hpp"
|
2019-08-19 20:03:45 +02:00
|
|
|
#include "../../types/IUiaData.h"
|
2019-05-03 00:29:04 +02:00
|
|
|
#include "../../cascadia/terminalcore/ITerminalApi.hpp"
|
|
|
|
#include "../../cascadia/terminalcore/ITerminalInput.hpp"
|
|
|
|
|
2021-07-15 01:41:22 +02:00
|
|
|
#include <til/ticket_lock.h>
|
|
|
|
|
2021-05-17 06:20:09 +02:00
|
|
|
static constexpr std::wstring_view linkPattern{ LR"(\b(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|$!:,.;]*[A-Za-z0-9+&@#/%=~_|$])" };
|
2021-05-05 20:12:55 +02:00
|
|
|
static constexpr size_t TaskbarMinProgress{ 10 };
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// You have to forward decl the ICoreSettings here, instead of including the header.
|
|
|
|
// If you include the header, there will be compilation errors with other
|
|
|
|
// headers that include Terminal.hpp
|
2021-03-17 21:47:24 +01:00
|
|
|
namespace winrt::Microsoft::Terminal::Core
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
struct ICoreSettings;
|
2021-04-09 00:46:16 +02:00
|
|
|
struct ICoreAppearance;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace Microsoft::Terminal::Core
|
|
|
|
{
|
|
|
|
class Terminal;
|
|
|
|
}
|
|
|
|
|
Create tests that roundtrip output through a conpty to a Terminal (#4213)
## Summary of the Pull Request
This PR adds two tests:
* First, I started by writing a test where I could write output to the console host and inspect what output came out of conpty. This is the `ConptyOutputTests` in the host unit tests.
* Then I got crazy and thought _"what if I could take that output and dump it straight into the `Terminal`"_? Hence, the `ConptyRoundtripTests` were born, into the TerminalCore unit tests.
## References
Done in pursuit of #4200, but I felt this warranted it's own atomic PR
## PR Checklist
* [x] Doesn't close anything on it's own.
* [x] I work here
* [x] you better believe this adds tests
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
From the comment in `ConptyRoundtripTests`:
> This test class creates an in-proc conpty host as well as a Terminal, to
> validate that strings written to the conpty create the same resopnse on the
> terminal end. Tests can be written that validate both the contents of the
> host buffer as well as the terminal buffer. Everytime that
> `renderer.PaintFrame()` is called, the tests will validate the expected
> output, and then flush the output of the VtEngine straight to th
Also, some other bits had to be updated:
* The renderer needed to be able to survive without a thread, so I hadded a simple check that it actually had a thread before calling `pThread->NotifyPaint`
* Bits in `CommonState` used `NTSTATUS_FROM_HRESULT` which did _not_ work outside the host project. Since the `NTSTATUS` didn't seem that important, I replaced that with a `HRESULT`
* `CommonState` likes to initialize the console to some _weird_ defaults. I added an optional param to let us just use the defaults.
2020-01-17 17:40:12 +01:00
|
|
|
// fwdecl unittest classes
|
|
|
|
#ifdef UNIT_TESTING
|
2020-01-29 17:33:06 +01:00
|
|
|
namespace TerminalCoreUnitTests
|
|
|
|
{
|
|
|
|
class TerminalBufferTests;
|
2020-03-13 18:39:42 +01:00
|
|
|
class TerminalApiTest;
|
2020-01-29 17:33:06 +01:00
|
|
|
class ConptyRoundtripTests;
|
2020-06-12 21:51:37 +02:00
|
|
|
class ScrollTest;
|
2020-01-29 17:33:06 +01:00
|
|
|
};
|
Create tests that roundtrip output through a conpty to a Terminal (#4213)
## Summary of the Pull Request
This PR adds two tests:
* First, I started by writing a test where I could write output to the console host and inspect what output came out of conpty. This is the `ConptyOutputTests` in the host unit tests.
* Then I got crazy and thought _"what if I could take that output and dump it straight into the `Terminal`"_? Hence, the `ConptyRoundtripTests` were born, into the TerminalCore unit tests.
## References
Done in pursuit of #4200, but I felt this warranted it's own atomic PR
## PR Checklist
* [x] Doesn't close anything on it's own.
* [x] I work here
* [x] you better believe this adds tests
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
From the comment in `ConptyRoundtripTests`:
> This test class creates an in-proc conpty host as well as a Terminal, to
> validate that strings written to the conpty create the same resopnse on the
> terminal end. Tests can be written that validate both the contents of the
> host buffer as well as the terminal buffer. Everytime that
> `renderer.PaintFrame()` is called, the tests will validate the expected
> output, and then flush the output of the VtEngine straight to th
Also, some other bits had to be updated:
* The renderer needed to be able to survive without a thread, so I hadded a simple check that it actually had a thread before calling `pThread->NotifyPaint`
* Bits in `CommonState` used `NTSTATUS_FROM_HRESULT` which did _not_ work outside the host project. Since the `NTSTATUS` didn't seem that important, I replaced that with a `HRESULT`
* `CommonState` likes to initialize the console to some _weird_ defaults. I added an optional param to let us just use the defaults.
2020-01-17 17:40:12 +01:00
|
|
|
#endif
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
class Microsoft::Terminal::Core::Terminal final :
|
|
|
|
public Microsoft::Terminal::Core::ITerminalApi,
|
|
|
|
public Microsoft::Terminal::Core::ITerminalInput,
|
2019-08-19 20:03:45 +02:00
|
|
|
public Microsoft::Console::Render::IRenderData,
|
|
|
|
public Microsoft::Console::Types::IUiaData
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Terminal();
|
2019-10-11 23:02:09 +02:00
|
|
|
~Terminal(){};
|
|
|
|
Terminal(const Terminal&) = default;
|
|
|
|
Terminal(Terminal&&) = default;
|
|
|
|
Terminal& operator=(const Terminal&) = default;
|
|
|
|
Terminal& operator=(Terminal&&) = default;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
void Create(COORD viewportSize,
|
|
|
|
SHORT scrollbackLines,
|
|
|
|
Microsoft::Console::Render::IRenderTarget& renderTarget);
|
|
|
|
|
2021-03-17 21:47:24 +01:00
|
|
|
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
|
2019-06-11 22:27:09 +02:00
|
|
|
Microsoft::Console::Render::IRenderTarget& renderTarget);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2021-03-17 21:47:24 +01:00
|
|
|
void UpdateSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
|
2021-04-09 00:46:16 +02:00
|
|
|
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
|
Expose Text Attributes to UI Automation (#10336)
## 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
2021-07-10 01:21:35 +02:00
|
|
|
void SetFontInfo(const FontInfo& fontInfo);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// Write goes through the parser
|
|
|
|
void Write(std::wstring_view stringView);
|
|
|
|
|
2021-02-08 14:11:01 +01:00
|
|
|
// WritePastedText goes directly to the connection
|
|
|
|
void WritePastedText(std::wstring_view stringView);
|
|
|
|
|
2021-07-15 01:41:22 +02:00
|
|
|
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForReading();
|
|
|
|
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
short GetBufferHeight() const noexcept;
|
|
|
|
|
Search - add search box control and implement search experience (#3590)
<!-- 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)? -->
This is the PR for feature Search: #605
This PR includes the newly introduced SearchBoxControl in TermControl dir, which is the search bar for the search experience. And the codes that enable Search in Windows Terminal.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
The PR that migrates the Conhost search module: https://github.com/microsoft/terminal/pull/3279
Spec (still actively updating): https://github.com/microsoft/terminal/pull/3299
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #605
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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 -->
These functionalities are included in the search experience.
1. Search in Terminal text buffer.
2. Automatic wrap-around.
3. Search up or down switch by clicking different buttons.
4. Search case sensitively/insensitively by clicking a button. S. Move the search box to the top/bottom by clicking a button.
6. Close by clicking 'X'.
7. Open search by ctrl + F.
When the searchbox is open, the user could still interact with the terminal by clicking the terminal input area.
While I already have the search functionalities, currently there are still some known to-do works and I will keep updating my PR:
1. Optimize the search box UI, this includes:
1) Theme adaptation. The search box background and font color
should change according to the theme,
2) Add background. Currently the elements in search box are all
transparent. However, we need a background.
3) Move button should be highlighted once clicked.
2. Accessibility: search process should be able to performed without mouse. Once the search box is focused, the user should be able to navigate between all interactive elements on the searchbox using keyboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
To test:
1. checkout this branch.
2. Build the project.
3. Start Windows Terminal and press Ctrl+F
4. The search box should appear on the top right corner.
2019-12-17 16:52:37 +01:00
|
|
|
int ViewStartIndex() const noexcept;
|
|
|
|
int ViewEndIndex() const noexcept;
|
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma region ITerminalApi
|
2019-05-03 00:29:04 +02:00
|
|
|
// These methods are defined in TerminalApi.cpp
|
2020-01-03 19:44:27 +01:00
|
|
|
bool PrintString(std::wstring_view stringView) noexcept override;
|
|
|
|
bool ExecuteChar(wchar_t wch) noexcept override;
|
Refactor TerminalDispatch (graphics) to match AdaptDispatch (#6728)
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
2020-07-01 20:13:42 +02:00
|
|
|
TextAttribute GetTextAttributes() const noexcept override;
|
|
|
|
void SetTextAttributes(const TextAttribute& attrs) noexcept override;
|
2021-04-16 18:26:28 +02:00
|
|
|
Microsoft::Console::Types::Viewport GetBufferSize() noexcept override;
|
2020-01-03 19:44:27 +01:00
|
|
|
bool SetCursorPosition(short x, short y) noexcept override;
|
|
|
|
COORD GetCursorPosition() noexcept override;
|
2020-03-13 18:39:42 +01:00
|
|
|
bool SetCursorVisibility(const bool visible) noexcept override;
|
|
|
|
bool EnableCursorBlinking(const bool enable) noexcept override;
|
Remove unneeded VT-specific control character handling (#4289)
## Summary of the Pull Request
This PR removes all of the VT-specific functionality from the `WriteCharsLegacy` function that dealt with control characters, since those controls are now handled in the state machine when in VT mode. It also removes most of the control character handling from the `Terminal::_WriteBuffer` method for the same reason.
## References
This is a followup to PR #4171
## PR Checklist
* [x] Closes #3971
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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: https://github.com/microsoft/terminal/issues/780#issuecomment-570287435
## Detailed Description of the Pull Request / Additional comments
There are four changes to the `WriteCharsLegacy` implementation:
1. The `TAB` character had special case handling in VT mode which is now no longer required. This fixes a bug in the Python REPL editor (when run from a cmd shell in Windows Terminal), which would prevent you tabbing past the end of the line. It also fixes #3971.
2. Following on from point 1, the `WC_NONDESTRUCTIVE_TAB` flag could also now be removed. It only ever applied in VT mode, in which case the `TAB` character isn't handled in `WriteCharsLegacy`, so there isn't a need for a non-destructive version.
3. There used to be special case handling for a `BS` character at the beginning of the line when in VT mode, and that is also no longer required. This fixes an edge-case bug which would prevent a glyph being output for code point 8 when `ENABLE_PROCESSED_OUTPUT` was disabled.
4. There was quite a lot of special case handling for control characters in the "end-of-line wrap" implementation, which is no longer required. This fixes a bug which would prevent "low ASCII" characters from wrapping when output at the end of a line.
Then in the `Terminal::_WriteBuffer` implementation, I've simply removed all control character handling, except for `LF`. The Terminal is always in VT mode, so the control characters are always handled by the state machine. The exception for the `LF` character is simply because it doesn't have a proper implementation yet, so it still passes the character through to `_WriteBuffer`. That will get cleaned up eventually, but I thought that could wait for a later PR.
Finally, with the removal of the VT mode handling in `WriteCharsLegacy`, there was no longer a need for the `SCREEN_INFORMATION::InVTMode` method to be publicly accessible. That has now been made private.
## Validation Steps Performed
I've only tested manually, making sure the conhost and Windows Terminal still basically work, and confirming that the above-mentioned bugs are fixed by these changes.
2020-01-29 20:18:46 +01:00
|
|
|
bool CursorLineFeed(const bool withReturn) noexcept override;
|
2020-01-03 19:44:27 +01:00
|
|
|
bool DeleteCharacter(const size_t count) noexcept override;
|
|
|
|
bool InsertCharacter(const size_t count) noexcept override;
|
|
|
|
bool EraseCharacters(const size_t numChars) noexcept override;
|
|
|
|
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
|
|
|
|
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
|
2020-10-01 03:00:06 +02:00
|
|
|
bool WarningBell() noexcept override;
|
2020-01-03 19:44:27 +01:00
|
|
|
bool SetWindowTitle(std::wstring_view title) noexcept override;
|
Consolidate the color palette APIs (#11784)
This PR merges the default colors and cursor color into the main color
table, enabling us to simplify the `ConGetSet` and `ITerminalApi`
interfaces, with just two methods required for getting and setting any
form of color palette entry.
The is a follow-up to the color table standardization in #11602, and a
another small step towards de-duplicating `AdaptDispatch` and
`TerminalDispatch` for issue #3849. It should also make it easier to
support color queries (#3718) and a configurable bold color (#5682) in
the future.
On the conhost side, default colors could originally be either indexed
positions in the 16-color table, or separate standalone RGB values. With
the new system, the default colors will always be in the color table, so
we just need to track their index positions.
To make this work, those positions need to be calculated at startup
based on the loaded registry/shortcut settings, and updated when
settings are changed (this is handled in
`CalculateDefaultColorIndices`). But the plus side is that it's now much
easier to lookup the default color values for rendering.
For now the default colors in Windows Terminal use hardcoded positions,
because it doesn't need indexed default colors like conhost. But in the
future I'd like to extend the index handling to both terminals, so we
can eventually support the VT525 indexed color operations.
As for the cursor color, that was previously stored in the `Cursor`
class, which meant that it needed to be copied around in various places
where cursors were being instantiated. Now that it's managed separately
in the color table, a lot of that code is no longer required.
## Validation
Some of the unit test initialization code needed to be updated to setup
the color table and default index values as required for the new system.
There were also some adjustments needed to account for API changes, in
particular for methods that now take index values for the default colors
in place of COLORREFs. But for the most part, the essential behavior of
the tests remains unchanged.
I've also run a variety of manual tests looking at the legacy console
APIs as well as the various VT color sequences, and checking that
everything works as expected when color schemes are changed, both in
Windows Terminal and conhost, and in the latter case with both indexed
colors and RGB values.
Closes #11768
2021-11-23 19:28:55 +01:00
|
|
|
COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override;
|
2020-01-03 19:44:27 +01:00
|
|
|
bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override;
|
|
|
|
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
|
2020-03-13 01:44:28 +01:00
|
|
|
|
2021-10-26 23:12:22 +02:00
|
|
|
bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept override;
|
|
|
|
|
2020-07-09 13:25:30 +02:00
|
|
|
bool SetScreenMode(const bool reverseMode) noexcept override;
|
2021-01-22 06:11:11 +01:00
|
|
|
bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override;
|
|
|
|
bool IsXtermBracketedPasteModeEnabled() const noexcept override;
|
2020-03-13 01:44:28 +01:00
|
|
|
|
|
|
|
bool IsVtInputEnabled() const noexcept override;
|
2020-06-30 03:55:40 +02:00
|
|
|
|
|
|
|
bool CopyToClipboard(std::wstring_view content) noexcept override;
|
2020-09-03 19:52:39 +02:00
|
|
|
|
|
|
|
bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept override;
|
|
|
|
bool EndHyperlink() noexcept override;
|
2020-11-18 23:24:11 +01:00
|
|
|
|
2021-05-05 20:12:55 +02:00
|
|
|
bool SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept override;
|
2021-01-11 19:01:38 +01:00
|
|
|
bool SetWorkingDirectory(std::wstring_view uri) noexcept override;
|
|
|
|
std::wstring_view GetWorkingDirectory() noexcept override;
|
2021-02-18 03:31:52 +01:00
|
|
|
|
|
|
|
bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) noexcept override;
|
|
|
|
bool PopGraphicsRendition() noexcept override;
|
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma region ITerminalInput
|
2019-05-03 00:29:04 +02:00
|
|
|
// These methods are defined in Terminal.cpp
|
2020-06-09 00:31:28 +02:00
|
|
|
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
|
2020-08-08 01:21:09 +02:00
|
|
|
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
2020-04-07 21:09:28 +02:00
|
|
|
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
|
2019-10-11 23:02:09 +02:00
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
void UserScrollViewport(const int viewTop) override;
|
2020-01-03 19:44:27 +01:00
|
|
|
int GetScrollOffset() noexcept override;
|
2019-11-13 03:12:43 +01:00
|
|
|
|
|
|
|
void TrySnapOnInput() override;
|
2020-03-13 01:44:28 +01:00
|
|
|
bool IsTrackingMouseInput() const noexcept;
|
2020-09-03 19:52:39 +02:00
|
|
|
|
|
|
|
std::wstring GetHyperlinkAtPosition(const COORD position);
|
2020-09-10 23:59:56 +02:00
|
|
|
uint16_t GetHyperlinkIdAtPosition(const COORD position);
|
2020-10-28 21:24:43 +01:00
|
|
|
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const COORD position);
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-08-19 20:03:45 +02:00
|
|
|
#pragma region IBaseData(base to IRenderData and IUiaData)
|
2019-05-03 00:29:04 +02:00
|
|
|
Microsoft::Console::Types::Viewport GetViewport() noexcept override;
|
Search - add search box control and implement search experience (#3590)
<!-- 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)? -->
This is the PR for feature Search: #605
This PR includes the newly introduced SearchBoxControl in TermControl dir, which is the search bar for the search experience. And the codes that enable Search in Windows Terminal.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
The PR that migrates the Conhost search module: https://github.com/microsoft/terminal/pull/3279
Spec (still actively updating): https://github.com/microsoft/terminal/pull/3299
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #605
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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 -->
These functionalities are included in the search experience.
1. Search in Terminal text buffer.
2. Automatic wrap-around.
3. Search up or down switch by clicking different buttons.
4. Search case sensitively/insensitively by clicking a button. S. Move the search box to the top/bottom by clicking a button.
6. Close by clicking 'X'.
7. Open search by ctrl + F.
When the searchbox is open, the user could still interact with the terminal by clicking the terminal input area.
While I already have the search functionalities, currently there are still some known to-do works and I will keep updating my PR:
1. Optimize the search box UI, this includes:
1) Theme adaptation. The search box background and font color
should change according to the theme,
2) Add background. Currently the elements in search box are all
transparent. However, we need a background.
3) Move button should be highlighted once clicked.
2. Accessibility: search process should be able to performed without mouse. Once the search box is focused, the user should be able to navigate between all interactive elements on the searchbox using keyboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
To test:
1. checkout this branch.
2. Build the project.
3. Start Windows Terminal and press Ctrl+F
4. The search box should appear on the top right corner.
2019-12-17 16:52:37 +01:00
|
|
|
COORD GetTextBufferEndPosition() const noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
const TextBuffer& GetTextBuffer() noexcept override;
|
|
|
|
const FontInfo& GetFontInfo() noexcept override;
|
Expose Text Attributes to UI Automation (#10336)
## 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
2021-07-10 01:21:35 +02:00
|
|
|
std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
|
2019-08-19 20:03:45 +02:00
|
|
|
|
|
|
|
void LockConsole() noexcept override;
|
|
|
|
void UnlockConsole() noexcept override;
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region IRenderData
|
|
|
|
// These methods are defined in TerminalRenderData.cpp
|
2019-05-03 00:29:04 +02:00
|
|
|
const TextAttribute GetDefaultBrushColors() noexcept override;
|
|
|
|
COORD GetCursorPosition() const noexcept override;
|
|
|
|
bool IsCursorVisible() const noexcept override;
|
|
|
|
bool IsCursorOn() const noexcept override;
|
|
|
|
ULONG GetCursorHeight() const noexcept override;
|
|
|
|
ULONG GetCursorPixelWidth() const noexcept override;
|
|
|
|
CursorType GetCursorStyle() const noexcept override;
|
|
|
|
COLORREF GetCursorColor() const noexcept override;
|
Show a double width cursor for double width characters (#5319)
# 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.
2020-04-15 21:23:06 +02:00
|
|
|
bool IsCursorDoubleWidth() const override;
|
2020-03-13 01:54:43 +01:00
|
|
|
bool IsScreenReversed() const noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
const std::vector<Microsoft::Console::Render::RenderOverlay> GetOverlays() const noexcept override;
|
|
|
|
const bool IsGridLineDrawingAllowed() noexcept override;
|
2020-09-03 19:52:39 +02:00
|
|
|
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
|
|
|
|
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
|
2020-10-28 21:24:43 +01:00
|
|
|
const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
|
2019-08-19 20:03:45 +02:00
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region IUiaData
|
2019-05-03 00:29:04 +02:00
|
|
|
std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept override;
|
2020-01-03 19:44:27 +01:00
|
|
|
const bool IsSelectionActive() const noexcept override;
|
2020-03-18 22:03:51 +01:00
|
|
|
const bool IsBlockSelection() const noexcept override;
|
Accessibility: Set-up UIA Tree (#1691)
**The Basics of Accessibility**
- [What is a User Interaction Automation (UIA) Tree?](https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-tree-overview)
- Other projects (i.e.: Narrator) can take advantage of this UIA tree and are used to present information within it.
- Some things like XAML already have a UIA Tree. So some UIA tree navigation and features are already there. It's just a matter of getting them hooked up and looking right.
**Accessibility in our Project**
There's a few important classes...
regarding Accessibility...
- **WindowUiaProvider**: This sets up the UIA tree for a window. So this is the top-level for the UIA tree.
- **ScreenInfoUiaProvider**: This sets up the UIA tree for a terminal buffer.
- **UiaTextRange**: This is essential to interacting with the UIA tree for the terminal buffer. Actually gets portions of the buffer and presents them.
regarding the Windows Terminal window...
- **BaseWindow**: The foundation to a window. Deals with HWNDs and that kind of stuff.
- **IslandWindow**: This extends `BaseWindow` and is actually what holds our Windows Terminal
- **NonClientIslandWindow**: An extension of the `IslandWindow`
regarding ConHost...
- **IConsoleWindow**: This is an interface for the console window.
- **Window**: This is the actual window for ConHost. Extends `IConsoleWindow`
- `IConsoleWindow` changes:
- move into `Microsoft::Console::Types` (a shared space)
- Have `IslandWindow` extend it
- `WindowUiaProvider` changes:
- move into `Microsoft::Console::Types` (a shared space)
- Hook up `WindowUiaProvider` to IslandWindow (yay! we now have a tree)
### Changes to the WindowUiaProvider
As mentioned earlier, the WindowUiaProvider is the top-level UIA provider for our projects. To reuse as much code as possible, I created `Microsoft::Console::Types::WindowUiaProviderBase`. Any existing functions that reference a `ScreenInfoUiaProvider` were virtual-ized.
In each project, a `WindowUiaProvider : WindowUiaProviderBase` was created to define those virtual functions. Note that that will be the main difference between ConHost and Windows Terminal moving forward: how many TextBuffers are on the screen.
So, ConHost should be the same as before, with only one `ScreenInfoUiaProvider`, whereas Windows Terminal needs to (1) update which one is on the screen and (2) may have multiple on the screen.
🚨 Windows Terminal doesn't have the `ScreenInfoUiaProvider` hooked up yet. We'll have all the XAML elements in the UIA tree. But, since `TermControl` is a custom XAML Control, I need to hook up the `ScreenInfoUiaProvider` to it. This work will be done in a new PR and resolve GitHub Issue #1352.
### Moved to `Microsoft::Console::Types`
These files got moved to a shared area so that they can be used by both ConHost and Windows Terminal.
This means that any references to the `ServiceLocator` had to be removed.
- `IConsoleWindow`
- Windows Terminal: `IslandWindow : IConsoleWindow`
- `ScreenInfoUiaProvider`
- all references to `ServiceLocator` and `SCREEN_INFORMATION` were removed. `IRenderData` was used to accomplish this. Refer to next section for more details.
- `UiaTextRange`
- all references to `ServiceLocator` and `SCREEN_INFORMATION` were removed. `IRenderData` was used to accomplish this. Refer to next section for more details.
- since most of the functions were `static`, that means that an `IRenderData` had to be added into most of them.
### Changes to IRenderData
Since `IRenderData` is now being used to abstract out `ServiceLocator` and `SCREEN_INFORMATION`, I had to add a few functions here:
- `bool IsAreaSelected()`
- `void ClearSelection()`
- `void SelectNewRegion(...)`
- `HRESULT SearchForText(...)`
`SearchForText()` is a problem here. The overall new design is great! But Windows Terminal doesn't have a way to search for text in the buffer yet, whereas ConHost does. So I'm punting on this issue for now. It looks nasty, but just look at all the other pretty things here. :)
2019-07-30 00:21:15 +02:00
|
|
|
void ClearSelection() override;
|
|
|
|
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
2020-02-21 00:03:50 +01:00
|
|
|
const COORD GetSelectionAnchor() const noexcept override;
|
2020-02-28 01:42:26 +01:00
|
|
|
const COORD GetSelectionEnd() const noexcept override;
|
Eliminate more transient allocations: Titles and invalid rectangles and bitmap runs and utf8 conversions (#8621)
## 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.
2021-02-16 21:52:33 +01:00
|
|
|
const std::wstring_view GetConsoleTitle() const noexcept override;
|
2019-11-14 23:36:41 +01:00
|
|
|
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
|
2021-09-24 00:14:03 +02:00
|
|
|
const bool IsUiaDataInitialized() const noexcept override;
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
void SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept;
|
2020-10-01 03:00:06 +02:00
|
|
|
void SetWarningBellCallback(std::function<void()> pfn) noexcept;
|
Split `TermControl` into a Core, Interactivity, and Control layer (#9820)
## 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.
2021-04-27 17:50:45 +02:00
|
|
|
void SetTitleChangedCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
2020-08-08 01:07:42 +02:00
|
|
|
void SetTabColorChangedCallback(std::function<void(const std::optional<til::color>)> pfn) noexcept;
|
Split `TermControl` into a Core, Interactivity, and Control layer (#9820)
## 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.
2021-04-27 17:50:45 +02:00
|
|
|
void SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
2019-05-03 00:29:04 +02:00
|
|
|
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
|
2020-03-31 01:21:47 +02:00
|
|
|
void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
|
Introduce MS.Term.Core.Color to replace W.U.Color for Core/Control/TSM (#9658)
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!
2021-03-30 22:15:49 +02:00
|
|
|
void SetBackgroundCallback(std::function<void(const til::color)> pfn) noexcept;
|
2020-11-18 23:24:11 +01:00
|
|
|
void TaskbarProgressChangedCallback(std::function<void()> pfn) noexcept;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Show a double width cursor for double width characters (#5319)
# 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.
2020-04-15 21:23:06 +02:00
|
|
|
void SetCursorOn(const bool isOn);
|
2019-05-23 19:44:27 +02:00
|
|
|
bool IsCursorBlinkingAllowed() const noexcept;
|
2019-05-14 03:25:54 +02:00
|
|
|
|
2021-05-17 06:20:09 +02:00
|
|
|
void UpdatePatternsUnderLock() noexcept;
|
2020-10-28 21:24:43 +01:00
|
|
|
void ClearPatternTree() noexcept;
|
|
|
|
|
2020-08-08 01:07:42 +02:00
|
|
|
const std::optional<til::color> GetTabColor() const noexcept;
|
|
|
|
|
Add support for the "blink" graphic rendition attribute (#7490)
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=1m55s
Closes #7388
2020-09-22 01:21:33 +02:00
|
|
|
Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept;
|
|
|
|
|
2020-11-18 23:24:11 +01:00
|
|
|
const size_t GetTaskbarState() const noexcept;
|
|
|
|
const size_t GetTaskbarProgress() const noexcept;
|
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma region TextSelection
|
2019-06-19 00:53:29 +02:00
|
|
|
// These methods are defined in TerminalSelection.cpp
|
2021-09-23 21:24:32 +02:00
|
|
|
enum class SelectionDirection
|
2020-02-28 01:42:26 +01:00
|
|
|
{
|
2021-09-23 21:24:32 +02:00
|
|
|
Left,
|
|
|
|
Right,
|
|
|
|
Up,
|
|
|
|
Down
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class SelectionExpansion
|
|
|
|
{
|
|
|
|
Char,
|
2020-02-28 01:42:26 +01:00
|
|
|
Word,
|
2021-09-23 21:24:32 +02:00
|
|
|
Line, // Mouse selection only!
|
|
|
|
Viewport,
|
|
|
|
Buffer
|
2020-02-28 01:42:26 +01:00
|
|
|
};
|
2021-09-23 21:24:32 +02:00
|
|
|
void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode);
|
2019-05-03 00:29:04 +02:00
|
|
|
void SetSelectionAnchor(const COORD position);
|
2021-09-23 21:24:32 +02:00
|
|
|
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
|
2020-02-28 01:42:26 +01:00
|
|
|
void SetBlockSelection(const bool isEnabled) noexcept;
|
2021-09-23 21:24:32 +02:00
|
|
|
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode);
|
|
|
|
|
|
|
|
using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
|
|
|
|
static UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Split `TermControl` into a Core, Interactivity, and Control layer (#9820)
## 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.
2021-04-27 17:50:45 +02:00
|
|
|
const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
|
2019-06-11 22:27:09 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
private:
|
2019-05-03 00:29:04 +02:00
|
|
|
std::function<void(std::wstring&)> _pfnWriteInput;
|
2020-10-01 03:00:06 +02:00
|
|
|
std::function<void()> _pfnWarningBell;
|
Split `TermControl` into a Core, Interactivity, and Control layer (#9820)
## 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.
2021-04-27 17:50:45 +02:00
|
|
|
std::function<void(std::wstring_view)> _pfnTitleChanged;
|
|
|
|
std::function<void(std::wstring_view)> _pfnCopyToClipboard;
|
2021-07-15 01:41:22 +02:00
|
|
|
|
|
|
|
// I've specifically put this instance here as it requires
|
|
|
|
// alignas(std::hardware_destructive_interference_size)
|
|
|
|
// for best performance.
|
|
|
|
//
|
|
|
|
// But we can abuse the fact that the surrounding members rarely change and are huge
|
|
|
|
// (std::function is like 64 bytes) to create some natural padding without wasting space.
|
|
|
|
til::ticket_lock _readWriteLock;
|
2021-10-01 00:15:20 +02:00
|
|
|
#ifndef NDEBUG
|
|
|
|
DWORD _lastLocker;
|
|
|
|
#endif
|
2021-07-15 01:41:22 +02:00
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
|
Introduce MS.Term.Core.Color to replace W.U.Color for Core/Control/TSM (#9658)
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!
2021-03-30 22:15:49 +02:00
|
|
|
std::function<void(const til::color)> _pfnBackgroundColorChanged;
|
2020-03-31 01:21:47 +02:00
|
|
|
std::function<void()> _pfnCursorPositionChanged;
|
2020-08-08 01:07:42 +02:00
|
|
|
std::function<void(const std::optional<til::color>)> _pfnTabColorChanged;
|
2020-11-18 23:24:11 +01:00
|
|
|
std::function<void()> _pfnTaskbarProgressChanged;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
|
|
|
std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput;
|
|
|
|
|
2020-06-09 23:47:13 +02:00
|
|
|
std::optional<std::wstring> _title;
|
2019-11-22 01:18:24 +01:00
|
|
|
std::wstring _startingTitle;
|
2020-08-08 01:07:42 +02:00
|
|
|
std::optional<til::color> _tabColor;
|
2020-11-20 05:36:18 +01:00
|
|
|
std::optional<til::color> _startingTabColor;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Introduce MS.Term.Core.Color to replace W.U.Color for Core/Control/TSM (#9658)
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!
2021-03-30 22:15:49 +02:00
|
|
|
// This is still stored as a COLORREF because it interacts with some code in ConTypes
|
Consolidate the color palette APIs (#11784)
This PR merges the default colors and cursor color into the main color
table, enabling us to simplify the `ConGetSet` and `ITerminalApi`
interfaces, with just two methods required for getting and setting any
form of color palette entry.
The is a follow-up to the color table standardization in #11602, and a
another small step towards de-duplicating `AdaptDispatch` and
`TerminalDispatch` for issue #3849. It should also make it easier to
support color queries (#3718) and a configurable bold color (#5682) in
the future.
On the conhost side, default colors could originally be either indexed
positions in the 16-color table, or separate standalone RGB values. With
the new system, the default colors will always be in the color table, so
we just need to track their index positions.
To make this work, those positions need to be calculated at startup
based on the loaded registry/shortcut settings, and updated when
settings are changed (this is handled in
`CalculateDefaultColorIndices`). But the plus side is that it's now much
easier to lookup the default color values for rendering.
For now the default colors in Windows Terminal use hardcoded positions,
because it doesn't need indexed default colors like conhost. But in the
future I'd like to extend the index handling to both terminals, so we
can eventually support the VT525 indexed color operations.
As for the cursor color, that was previously stored in the `Cursor`
class, which meant that it needed to be copied around in various places
where cursors were being instantiated. Now that it's managed separately
in the color table, a lot of that code is no longer required.
## Validation
Some of the unit test initialization code needed to be updated to setup
the color table and default index values as required for the new system.
There were also some adjustments needed to account for API changes, in
particular for methods that now take index values for the default colors
in place of COLORREFs. But for the most part, the essential behavior of
the tests remains unchanged.
I've also run a variety of manual tests looking at the legacy console
APIs as well as the various VT color sequences, and checking that
everything works as expected when color schemes are changed, both in
Windows Terminal and conhost, and in the latter case with both indexed
colors and RGB values.
Closes #11768
2021-11-23 19:28:55 +01:00
|
|
|
std::array<COLORREF, TextColor::TABLE_SIZE> _colorTable;
|
2020-09-04 22:36:09 +02:00
|
|
|
CursorType _defaultCursorShape;
|
2020-07-09 13:25:30 +02:00
|
|
|
bool _screenReversed;
|
Add support for the "blink" graphic rendition attribute (#7490)
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=1m55s
Closes #7388
2020-09-22 01:21:33 +02:00
|
|
|
mutable Microsoft::Console::Render::BlinkingState _blinkingState;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
bool _snapOnInput;
|
2020-06-05 18:11:41 +02:00
|
|
|
bool _altGrAliasing;
|
2019-11-22 01:18:24 +01:00
|
|
|
bool _suppressApplicationTitle;
|
2021-01-22 06:11:11 +01:00
|
|
|
bool _bracketedPasteMode;
|
2021-04-24 00:36:51 +02:00
|
|
|
bool _trimBlockSelection;
|
Add an ENUM setting for disabling rendering "intense" text as bold (#10759)
## 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"
```
2021-08-16 15:45:56 +02:00
|
|
|
bool _intenseIsBright;
|
2021-10-08 00:43:17 +02:00
|
|
|
bool _adjustIndistinguishableColors;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-11-18 23:24:11 +01:00
|
|
|
size_t _taskbarState;
|
|
|
|
size_t _taskbarProgress;
|
|
|
|
|
2020-10-28 21:24:43 +01:00
|
|
|
size_t _hyperlinkPatternId;
|
|
|
|
|
2021-01-11 19:01:38 +01:00
|
|
|
std::wstring _workingDirectory;
|
Expose Text Attributes to UI Automation (#10336)
## 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
2021-07-10 01:21:35 +02:00
|
|
|
|
|
|
|
// This default fake font value is only used to check if the font is a raster font.
|
|
|
|
// Otherwise, the font is changed to a real value with the renderer via TriggerFontChange.
|
|
|
|
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
|
2019-08-15 01:41:43 +02:00
|
|
|
#pragma region Text Selection
|
2020-02-28 01:42:26 +01:00
|
|
|
// a selection is represented as a range between two COORDs (start and end)
|
|
|
|
// the pivot is the COORD that remains selected when you extend a selection in any direction
|
|
|
|
// this is particularly useful when a word selection is extended over its starting point
|
|
|
|
// see TerminalSelection.cpp for more information
|
|
|
|
struct SelectionAnchors
|
2019-08-15 01:41:43 +02:00
|
|
|
{
|
2020-02-28 01:42:26 +01:00
|
|
|
COORD start;
|
|
|
|
COORD end;
|
|
|
|
COORD pivot;
|
2019-08-15 01:41:43 +02:00
|
|
|
};
|
2020-02-28 01:42:26 +01:00
|
|
|
std::optional<SelectionAnchors> _selection;
|
|
|
|
bool _blockSelection;
|
2019-07-12 01:06:18 +02:00
|
|
|
std::wstring _wordDelimiters;
|
2021-09-23 21:24:32 +02:00
|
|
|
SelectionExpansion _multiClickSelectionMode;
|
2019-08-15 01:41:43 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// TODO: These members are not shared by an alt-buffer. They should be
|
|
|
|
// encapsulated, such that a Terminal can have both a main and alt buffer.
|
|
|
|
std::unique_ptr<TextBuffer> _buffer;
|
|
|
|
Microsoft::Console::Types::Viewport _mutableViewport;
|
|
|
|
SHORT _scrollbackLines;
|
|
|
|
|
|
|
|
// _scrollOffset is the number of lines above the viewport that are currently visible
|
|
|
|
// If _scrollOffset is 0, then the visible region of the buffer is the viewport.
|
|
|
|
int _scrollOffset;
|
|
|
|
// TODO this might not be the value we want to store.
|
ci: run spell check in CI, fix remaining issues (#4799)
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
2020-03-25 19:02:53 +01:00
|
|
|
// We might want to store the height in the scrollback that's currently visible.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Think on this some more.
|
|
|
|
// For example: While looking at the scrollback, we probably want the visible region to "stick"
|
|
|
|
// to the region they scrolled to. If that were the case, then every time we move _mutableViewport,
|
|
|
|
// we'd also need to update _offset.
|
|
|
|
// However, if we just stored it as a _visibleTop, then that point would remain fixed -
|
|
|
|
// Though if _visibleTop == _mutableViewport.Top, then we'd need to make sure to update
|
|
|
|
// _visibleTop as well.
|
|
|
|
// Additionally, maybe some people want to scroll into the history, then have that scroll out from
|
|
|
|
// underneath them, while others would prefer to anchor it in place.
|
2020-02-10 21:40:01 +01:00
|
|
|
// Either way, we should make this behavior controlled by a setting.
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-10-28 21:24:43 +01:00
|
|
|
interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
|
|
|
|
void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
|
|
|
|
void _InvalidateFromCoords(const COORD start, const COORD end);
|
|
|
|
|
2020-04-07 21:09:28 +02:00
|
|
|
// Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
|
|
|
|
struct KeyEventCodes
|
|
|
|
{
|
|
|
|
WORD VirtualKey;
|
|
|
|
WORD ScanCode;
|
|
|
|
};
|
|
|
|
std::optional<KeyEventCodes> _lastKeyEventCodes;
|
|
|
|
|
2019-10-01 18:15:30 +02:00
|
|
|
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
|
2020-04-07 21:09:28 +02:00
|
|
|
static WORD _VirtualKeyFromScanCode(const WORD scanCode) noexcept;
|
|
|
|
static WORD _VirtualKeyFromCharacter(const wchar_t ch) noexcept;
|
2019-10-01 18:15:30 +02:00
|
|
|
static wchar_t _CharacterFromKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states) noexcept;
|
|
|
|
|
2020-04-07 21:09:28 +02:00
|
|
|
void _StoreKeyEvent(const WORD vkey, const WORD scanCode);
|
|
|
|
WORD _TakeVirtualKeyFromLastKeyEvent(const WORD scanCode) noexcept;
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
int _VisibleStartIndex() const noexcept;
|
Search - add search box control and implement search experience (#3590)
<!-- 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)? -->
This is the PR for feature Search: #605
This PR includes the newly introduced SearchBoxControl in TermControl dir, which is the search bar for the search experience. And the codes that enable Search in Windows Terminal.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
The PR that migrates the Conhost search module: https://github.com/microsoft/terminal/pull/3279
Spec (still actively updating): https://github.com/microsoft/terminal/pull/3299
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #605
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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 -->
These functionalities are included in the search experience.
1. Search in Terminal text buffer.
2. Automatic wrap-around.
3. Search up or down switch by clicking different buttons.
4. Search case sensitively/insensitively by clicking a button. S. Move the search box to the top/bottom by clicking a button.
6. Close by clicking 'X'.
7. Open search by ctrl + F.
When the searchbox is open, the user could still interact with the terminal by clicking the terminal input area.
While I already have the search functionalities, currently there are still some known to-do works and I will keep updating my PR:
1. Optimize the search box UI, this includes:
1) Theme adaptation. The search box background and font color
should change according to the theme,
2) Add background. Currently the elements in search box are all
transparent. However, we need a background.
3) Move button should be highlighted once clicked.
2. Accessibility: search process should be able to performed without mouse. Once the search box is focused, the user should be able to navigate between all interactive elements on the searchbox using keyboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
To test:
1. checkout this branch.
2. Build the project.
3. Start Windows Terminal and press Ctrl+F
4. The search box should appear on the top right corner.
2019-12-17 16:52:37 +01:00
|
|
|
int _VisibleEndIndex() const noexcept;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
Microsoft::Console::Types::Viewport _GetMutableViewport() const noexcept;
|
|
|
|
Microsoft::Console::Types::Viewport _GetVisibleViewport() const noexcept;
|
|
|
|
|
|
|
|
void _InitializeColorTable();
|
|
|
|
|
|
|
|
void _WriteBuffer(const std::wstring_view& stringView);
|
|
|
|
|
Remove unneeded VT-specific control character handling (#4289)
## Summary of the Pull Request
This PR removes all of the VT-specific functionality from the `WriteCharsLegacy` function that dealt with control characters, since those controls are now handled in the state machine when in VT mode. It also removes most of the control character handling from the `Terminal::_WriteBuffer` method for the same reason.
## References
This is a followup to PR #4171
## PR Checklist
* [x] Closes #3971
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be 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: https://github.com/microsoft/terminal/issues/780#issuecomment-570287435
## Detailed Description of the Pull Request / Additional comments
There are four changes to the `WriteCharsLegacy` implementation:
1. The `TAB` character had special case handling in VT mode which is now no longer required. This fixes a bug in the Python REPL editor (when run from a cmd shell in Windows Terminal), which would prevent you tabbing past the end of the line. It also fixes #3971.
2. Following on from point 1, the `WC_NONDESTRUCTIVE_TAB` flag could also now be removed. It only ever applied in VT mode, in which case the `TAB` character isn't handled in `WriteCharsLegacy`, so there isn't a need for a non-destructive version.
3. There used to be special case handling for a `BS` character at the beginning of the line when in VT mode, and that is also no longer required. This fixes an edge-case bug which would prevent a glyph being output for code point 8 when `ENABLE_PROCESSED_OUTPUT` was disabled.
4. There was quite a lot of special case handling for control characters in the "end-of-line wrap" implementation, which is no longer required. This fixes a bug which would prevent "low ASCII" characters from wrapping when output at the end of a line.
Then in the `Terminal::_WriteBuffer` implementation, I've simply removed all control character handling, except for `LF`. The Terminal is always in VT mode, so the control characters are always handled by the state machine. The exception for the `LF` character is simply because it doesn't have a proper implementation yet, so it still passes the character through to `_WriteBuffer`. That will get cleaned up eventually, but I thought that could wait for a later PR.
Finally, with the removal of the VT mode handling in `WriteCharsLegacy`, there was no longer a need for the `SCREEN_INFORMATION::InVTMode` method to be publicly accessible. That has now been made private.
## Validation Steps Performed
I've only tested manually, making sure the conhost and Windows Terminal still basically work, and confirming that the above-mentioned bugs are fixed by these changes.
2020-01-29 20:18:46 +01:00
|
|
|
void _AdjustCursorPosition(const COORD proposedPosition);
|
|
|
|
|
2020-01-03 19:44:27 +01:00
|
|
|
void _NotifyScrollEvent() noexcept;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-03-31 01:21:47 +02:00
|
|
|
void _NotifyTerminalCursorPositionChanged() noexcept;
|
|
|
|
|
2019-06-19 00:53:29 +02:00
|
|
|
#pragma region TextSelection
|
|
|
|
// These methods are defined in TerminalSelection.cpp
|
2019-09-17 19:39:39 +02:00
|
|
|
std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
|
2020-06-25 02:47:13 +02:00
|
|
|
std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
|
2020-02-28 01:42:26 +01:00
|
|
|
std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
|
2019-09-17 19:39:39 +02:00
|
|
|
COORD _ConvertToBufferCell(const COORD viewportPos) const;
|
2021-09-23 21:24:32 +02:00
|
|
|
void _MoveByChar(SelectionDirection direction, COORD& pos);
|
|
|
|
void _MoveByWord(SelectionDirection direction, COORD& pos);
|
|
|
|
void _MoveByViewport(SelectionDirection direction, COORD& pos);
|
|
|
|
void _MoveByBuffer(SelectionDirection direction, COORD& pos);
|
2019-06-19 00:53:29 +02:00
|
|
|
#pragma endregion
|
Create tests that roundtrip output through a conpty to a Terminal (#4213)
## Summary of the Pull Request
This PR adds two tests:
* First, I started by writing a test where I could write output to the console host and inspect what output came out of conpty. This is the `ConptyOutputTests` in the host unit tests.
* Then I got crazy and thought _"what if I could take that output and dump it straight into the `Terminal`"_? Hence, the `ConptyRoundtripTests` were born, into the TerminalCore unit tests.
## References
Done in pursuit of #4200, but I felt this warranted it's own atomic PR
## PR Checklist
* [x] Doesn't close anything on it's own.
* [x] I work here
* [x] you better believe this adds tests
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
From the comment in `ConptyRoundtripTests`:
> This test class creates an in-proc conpty host as well as a Terminal, to
> validate that strings written to the conpty create the same resopnse on the
> terminal end. Tests can be written that validate both the contents of the
> host buffer as well as the terminal buffer. Everytime that
> `renderer.PaintFrame()` is called, the tests will validate the expected
> output, and then flush the output of the VtEngine straight to th
Also, some other bits had to be updated:
* The renderer needed to be able to survive without a thread, so I hadded a simple check that it actually had a thread before calling `pThread->NotifyPaint`
* Bits in `CommonState` used `NTSTATUS_FROM_HRESULT` which did _not_ work outside the host project. Since the `NTSTATUS` didn't seem that important, I replaced that with a `HRESULT`
* `CommonState` likes to initialize the console to some _weird_ defaults. I added an optional param to let us just use the defaults.
2020-01-17 17:40:12 +01:00
|
|
|
|
2021-02-18 03:31:52 +01:00
|
|
|
Microsoft::Console::VirtualTerminal::SgrStack _sgrStack;
|
|
|
|
|
2021-10-08 00:43:17 +02:00
|
|
|
void _MakeAdjustedColorArray();
|
|
|
|
std::array<std::array<COLORREF, 18>, 18> _adjustedForegroundColors;
|
|
|
|
|
Create tests that roundtrip output through a conpty to a Terminal (#4213)
## Summary of the Pull Request
This PR adds two tests:
* First, I started by writing a test where I could write output to the console host and inspect what output came out of conpty. This is the `ConptyOutputTests` in the host unit tests.
* Then I got crazy and thought _"what if I could take that output and dump it straight into the `Terminal`"_? Hence, the `ConptyRoundtripTests` were born, into the TerminalCore unit tests.
## References
Done in pursuit of #4200, but I felt this warranted it's own atomic PR
## PR Checklist
* [x] Doesn't close anything on it's own.
* [x] I work here
* [x] you better believe this adds tests
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
From the comment in `ConptyRoundtripTests`:
> This test class creates an in-proc conpty host as well as a Terminal, to
> validate that strings written to the conpty create the same resopnse on the
> terminal end. Tests can be written that validate both the contents of the
> host buffer as well as the terminal buffer. Everytime that
> `renderer.PaintFrame()` is called, the tests will validate the expected
> output, and then flush the output of the VtEngine straight to th
Also, some other bits had to be updated:
* The renderer needed to be able to survive without a thread, so I hadded a simple check that it actually had a thread before calling `pThread->NotifyPaint`
* Bits in `CommonState` used `NTSTATUS_FROM_HRESULT` which did _not_ work outside the host project. Since the `NTSTATUS` didn't seem that important, I replaced that with a `HRESULT`
* `CommonState` likes to initialize the console to some _weird_ defaults. I added an optional param to let us just use the defaults.
2020-01-17 17:40:12 +01:00
|
|
|
#ifdef UNIT_TESTING
|
2020-01-29 17:33:06 +01:00
|
|
|
friend class TerminalCoreUnitTests::TerminalBufferTests;
|
2020-03-13 18:39:42 +01:00
|
|
|
friend class TerminalCoreUnitTests::TerminalApiTest;
|
2020-01-29 17:33:06 +01:00
|
|
|
friend class TerminalCoreUnitTests::ConptyRoundtripTests;
|
2020-06-12 21:51:37 +02:00
|
|
|
friend class TerminalCoreUnitTests::ScrollTest;
|
Create tests that roundtrip output through a conpty to a Terminal (#4213)
## Summary of the Pull Request
This PR adds two tests:
* First, I started by writing a test where I could write output to the console host and inspect what output came out of conpty. This is the `ConptyOutputTests` in the host unit tests.
* Then I got crazy and thought _"what if I could take that output and dump it straight into the `Terminal`"_? Hence, the `ConptyRoundtripTests` were born, into the TerminalCore unit tests.
## References
Done in pursuit of #4200, but I felt this warranted it's own atomic PR
## PR Checklist
* [x] Doesn't close anything on it's own.
* [x] I work here
* [x] you better believe this adds tests
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
From the comment in `ConptyRoundtripTests`:
> This test class creates an in-proc conpty host as well as a Terminal, to
> validate that strings written to the conpty create the same resopnse on the
> terminal end. Tests can be written that validate both the contents of the
> host buffer as well as the terminal buffer. Everytime that
> `renderer.PaintFrame()` is called, the tests will validate the expected
> output, and then flush the output of the VtEngine straight to th
Also, some other bits had to be updated:
* The renderer needed to be able to survive without a thread, so I hadded a simple check that it actually had a thread before calling `pThread->NotifyPaint`
* Bits in `CommonState` used `NTSTATUS_FROM_HRESULT` which did _not_ work outside the host project. Since the `NTSTATUS` didn't seem that important, I replaced that with a `HRESULT`
* `CommonState` likes to initialize the console to some _weird_ defaults. I added an optional param to let us just use the defaults.
2020-01-17 17:40:12 +01:00
|
|
|
#endif
|
2019-05-03 00:29:04 +02:00
|
|
|
};
|