2019-05-03 00:29:04 +02:00
|
|
|
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Licensed under the MIT license.
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
- renderData.hpp
|
|
|
|
|
|
|
|
Abstract:
|
|
|
|
- This method provides an interface for rendering the final display based on the current console state
|
|
|
|
|
|
|
|
Author(s):
|
|
|
|
- Michael Niksa (miniksa) Nov 2015
|
|
|
|
--*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-11-25 22:02:10 +01:00
|
|
|
#include "../renderer/inc/IRenderData.hpp"
|
|
|
|
#include "../types/IUiaData.h"
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-08-19 20:03:45 +02:00
|
|
|
class RenderData final :
|
|
|
|
public Microsoft::Console::Render::IRenderData,
|
|
|
|
public Microsoft::Console::Types::IUiaData
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
public:
|
2019-08-19 20:03:45 +02:00
|
|
|
#pragma region BaseData
|
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;
|
2019-08-19 20:03:45 +02:00
|
|
|
|
|
|
|
std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept override;
|
|
|
|
|
|
|
|
void LockConsole() noexcept override;
|
|
|
|
void UnlockConsole() noexcept override;
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region IRenderData
|
2019-05-03 00:29:04 +02:00
|
|
|
const TextAttribute GetDefaultBrushColors() noexcept override;
|
|
|
|
|
Refactor the renderer color calculations (#6853)
This is a refactoring of the renderer color calculations to simplify the
implementation, and to make it easier to support additional
color-altering rendition attributes in the future (e.g. _faint_ and
_conceal_).
## References
* This is a followup to PRs #3817 and #6809, which introduced additional
complexity in the color calculations, and which suggested the need for
refactoring.
## Detailed Description of the Pull Request / Additional comments
When we added support for `DECSCNM`, that required the foreground and
background color lookup methods to be able to return the opposite of
what was requested when the reversed mode was set. That made those
methods unnecessarily complicated, and I thought we could simplify them
considerably just by combining the calculations into a single method
that derived both colors at the same time.
And since both conhost and Windows Terminal needed to perform the same
calculations, it also made sense to move that functionality into the
`TextAttribute` class, where it could easily be shared.
In general this way of doing things is a bit more efficient. However, it
does result in some unnecessary work when only one of the colors is
required, as is the case for the gridline painter. So to make that less
of an issue, I've reordered the gridline code a bit so it at least
avoids looking up the colors when no gridlines are needed.
## Validation Steps Performed
Because of the API changes, quite a lot of the unit tests had to be
updated. For example instead of verifying colors with two separate calls
to `LookupForegroundColor` and `LookupBackgroundColor`, that's now
achieved with a single `LookupAttributeColors` call, comparing against a
pair of values. The specifics of the tests haven't changed though, and
they're all still working as expected.
I've also manually confirmed that the various color sequences and
rendition attributes are rendering correctly with the new refactoring.
2020-07-11 00:26:34 +02:00
|
|
|
std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
COORD GetCursorPosition() const noexcept override;
|
|
|
|
bool IsCursorVisible() const noexcept override;
|
|
|
|
bool IsCursorOn() const noexcept override;
|
|
|
|
ULONG GetCursorHeight() const noexcept override;
|
|
|
|
CursorType GetCursorStyle() const noexcept override;
|
|
|
|
ULONG GetCursorPixelWidth() const noexcept override;
|
|
|
|
COLORREF GetCursorColor() const noexcept override;
|
Fix out-of-bounds exceptions in Set...{Buffer,Screen}Size (#8309)
This fixes a number of exceptions that can cause conhost to crash when
the buffer is resized in such a way that the viewport or cursor position
end up out of bounds.
Technically this is a fix for issue #256, although that has been closed
as "needs-repro".
The main fix was to add checks in the `SetConsoleScreenBufferSizeImpl`
and `SetConsoleScreenBufferInfoExImpl` methods, to make sure the
viewport doesn't extend past the bottom or right of the buffer after a
resize. If it has overflowed, we move the viewport back up or left until
it's back within the buffer boundaries. We also check if the cursor
position has ended up out of bounds, and if so, clamp it back inside the
buffer.
The `SCREEN_INFORMATION::SetViewport` was also a source of viewport
overflow problems, because it was mistakenly using inclusive coordinates
in its range checks, which resulted in them being off by one. That has
now been corrected to use exclusive coordinates.
Finally, the `IsCursorDoubleWidth` method was incorrectly marked as
`noexcept`, which was preventing its exceptions from being caught.
Ideally it shouldn't be throwing exceptions at all any more, but I've
removed the `noexcept` specifier, so if it does throw an exception,
it'll at least have more chance of recovering without a crash.
## Validation Steps Performed
I put together a few test cases (based on the reports in issues #276 and
#1976) which consistently caused conhost to crash, or to generate an
exception visible in the debug output. With this PR applied, those test
cases are no longer crashing or triggering exceptions.
Closes #1976
2020-11-17 22:17:51 +01:00
|
|
|
bool IsCursorDoubleWidth() const override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-03-13 01:54:43 +01:00
|
|
|
bool IsScreenReversed() const noexcept override;
|
|
|
|
|
2019-05-30 20:14:21 +02:00
|
|
|
const std::vector<Microsoft::Console::Render::RenderOverlay> GetOverlays() const noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
const bool IsGridLineDrawingAllowed() 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;
|
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
|
|
|
|
const bool IsSelectionActive() const 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;
|
2020-02-28 01:42:26 +01:00
|
|
|
const COORD GetSelectionEnd() const noexcept;
|
2019-11-14 23:36:41 +01:00
|
|
|
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
|
2019-08-19 20:03:45 +02:00
|
|
|
#pragma endregion
|
2019-05-03 00:29:04 +02:00
|
|
|
};
|