terminal/src/renderer/vt/XtermEngine.hpp
Mike Griese e5182fb3e8
Make Conpty emit wrapped lines as actually wrapped lines (#4415)
## Summary of the Pull Request

Changes how conpty emits text to preserve line-wrap state, and additionally adds rudimentary support to the Windows Terminal for wrapped lines.

## References

* Does _not_ fix (!) #3088, but that might be lower down in conhost. This makes wt behave like conhost, so at least there's that
* Still needs a proper deferred EOL wrap implementation in #780, which is left as a todo
* #4200 is the mega bucket with all this work
* MSFT:16485846 was the first attempt at this task, which caused the regression MSFT:18123777 so we backed it out.
* #4403 - I made sure this worked with that PR before I even sent #4403

## PR Checklist
* [x] Closes #405
* [x] Closes #3367 
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

I started with the following implementation:
When conpty is about to write the last column, note that we wrapped this line here. If the next character the vt renderer is told to paint get is supposed to be at the start of the following line, then we know that the previous line had wrapped, so we _won't_ emit the usual `\r\n` here, and we'll just continue emitting text.

However, this isn't _exactly_ right - if someone fills the row _exactly_ with text, the information that's available to the vt renderer isn't enough to know for sure if this line broke or not. It is possible for the client to write a full line of text, with a `\n` at the end, to manually break the line. So, I had to also add the `lineWrapped` param to the `IRenderEngine` interface, which is about half the files in this changelist.

## Validation Steps Performed
* Ran tests
* Checked how the Windows Terminal behaves with these changes
* Made sure that conhost/inception and gnome-terminal both act as you'd expect with wrapped lines from conpty
2020-02-27 16:40:11 +00:00

80 lines
3.1 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- XtermEngine.hpp
Abstract:
- This is the definition of the VT specific implementation of the renderer.
This is the xterm implementation, which supports advanced sequences such as
inserting and deleting lines, but only 16 colors.
This engine supports both xterm and xterm-ascii VT modes.
The difference being that xterm-ascii will render any characters above 0x7f
as '?', in order to support older legacy tools.
Author(s):
- Mike Griese (migrie) 01-Sept-2017
--*/
#pragma once
#include "vtrenderer.hpp"
namespace Microsoft::Console::Render
{
class XtermEngine : public VtEngine
{
public:
XtermEngine(_In_ wil::unique_hfile hPipe,
const Microsoft::Console::IDefaultColorProvider& colorProvider,
const Microsoft::Console::Types::Viewport initialViewport,
_In_reads_(cColorTable) const COLORREF* const ColorTable,
const WORD cColorTable,
const bool fUseAsciiOnly);
virtual ~XtermEngine() override = default;
[[nodiscard]] HRESULT StartPaint() noexcept override;
[[nodiscard]] HRESULT EndPaint() noexcept override;
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const COLORREF colorForeground,
const COLORREF colorBackground,
const WORD legacyColorAttribute,
const ExtendedAttributes extendedAttrs,
const bool isSettingDefaultBrushes) noexcept override;
[[nodiscard]] HRESULT PaintBufferLine(std::basic_string_view<Cluster> const clusters,
const COORD coord,
const bool trimLeft,
const bool lineWrapped) noexcept override;
[[nodiscard]] HRESULT ScrollFrame() noexcept override;
[[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
[[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override;
protected:
const COLORREF* const _ColorTable;
const WORD _cColorTable;
const bool _fUseAsciiOnly;
bool _usingUnderLine;
bool _needToDisableCursor;
bool _lastCursorIsVisible;
bool _nextCursorIsVisible;
[[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override;
[[nodiscard]] HRESULT _UpdateUnderline(const WORD wLegacyAttrs) noexcept;
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept override;
#ifdef UNIT_TESTING
friend class VtRendererTest;
friend class ConptyOutputTests;
#endif
};
}