From 8f418d10a6e23f1c09a698152978b051c7e30892 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 19 Dec 2025 23:08:03 +0100 Subject: [PATCH] Clean up SCREEN_INFORMATION even further (#19648) A continuation of #19645. Maintainer modifications were disabled, unfortunately. --- src/host/screenInfo.cpp | 1 - src/host/screenInfo.hpp | 290 +++++++++++++++------------------------- 2 files changed, 111 insertions(+), 180 deletions(-) diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index 6edfcf154c..51beb39822 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -23,7 +23,6 @@ SCREEN_INFORMATION::SCREEN_INFORMATION( const TextAttribute popupAttributes, const FontInfo fontInfo) : _pConsoleWindowMetrics{ pMetrics }, - _viewport(Viewport::Empty()), _PopupAttributes{ popupAttributes }, _currentFont{ fontInfo }, _desiredFont{ fontInfo } diff --git a/src/host/screenInfo.hpp b/src/host/screenInfo.hpp index fc93ed74f2..7f29af804a 100644 --- a/src/host/screenInfo.hpp +++ b/src/host/screenInfo.hpp @@ -20,24 +20,12 @@ Revision History: #pragma once #include "outputStream.hpp" - #include "../buffer/out/OutputCellRect.hpp" -#include "../buffer/out/TextAttribute.hpp" #include "../buffer/out/textBuffer.hpp" -#include "../buffer/out/textBufferCellIterator.hpp" -#include "../buffer/out/textBufferTextIterator.hpp" - -#include "IIoProvider.hpp" -#include "../terminal/parser/stateMachine.hpp" - +#include "../interactivity/inc/IWindowMetrics.hpp" +#include "../renderer/inc/FontInfoDesired.hpp" #include "../server/ObjectHeader.h" -#include "../interactivity/inc/IWindowMetrics.hpp" - -#include "../renderer/inc/FontInfo.hpp" -#include "../renderer/inc/FontInfoDesired.hpp" - -#include "../types/inc/Viewport.hpp" class ConversionAreaInfo; // forward decl window. circular reference class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console::IIoProvider @@ -62,103 +50,14 @@ public: SCREEN_INFORMATION* self; }; - [[nodiscard]] static NTSTATUS CreateInstance(_In_ til::size coordWindowSize, - const FontInfo fontInfo, - _In_ til::size coordScreenBufferSize, - const TextAttribute defaultAttributes, - const TextAttribute popupAttributes, - const UINT uiCursorSize, - _Outptr_ SCREEN_INFORMATION** const ppScreen); - - ~SCREEN_INFORMATION() override; - - void GetScreenBufferInformation(_Out_ til::size* pcoordSize, - _Out_ til::point* pcoordCursorPosition, - _Out_ til::inclusive_rect* psrWindow, - _Out_ PWORD pwAttributes, - _Out_ til::size* pcoordMaximumWindowSize, - _Out_ PWORD pwPopupAttributes, - _Out_writes_(COLOR_TABLE_SIZE) LPCOLORREF lpColorTable) const; - - void GetRequiredConsoleSizeInPixels(_Out_ til::size* const pRequiredSize) const; - - void MakeCurrentCursorVisible(); - void MakeCursorVisible(til::point position); - void SnapOnInput(WORD vkey); - SnapOnScopeExit SnapOnOutput() noexcept; - - void ClipToScreenBuffer(_Inout_ til::inclusive_rect* const psrClip) const; - - til::size GetMinWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const; - til::size GetMaxWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const; - til::size GetLargestWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const; - til::size GetScrollBarSizesInCharacters() const; - - Microsoft::Console::Types::Viewport GetBufferSize() const; - Microsoft::Console::Types::Viewport GetTerminalBufferSize() const; - - til::size GetScreenFontSize() const; - void UpdateFont(const FontInfo* const pfiNewFont); - void RefreshFontWithRenderer(); - - [[nodiscard]] NTSTATUS ResizeScreenBuffer(const til::size coordNewScreenSize, const bool fDoScrollBarUpdate); - struct ScrollBarState { til::size maxSize; til::rect viewport; bool isAltBuffer = false; }; - void UpdateScrollBars(); - ScrollBarState FetchScrollBarState(); - bool IsMaximizedBoth() const; - bool IsMaximizedX() const; - bool IsMaximizedY() const; - - const Microsoft::Console::Types::Viewport& GetViewport() const noexcept; - void SetViewport(const Microsoft::Console::Types::Viewport& newViewport, const bool updateBottom); - Microsoft::Console::Types::Viewport GetVirtualViewport() const noexcept; - Microsoft::Console::Types::Viewport GetVtPageArea() const noexcept; - - void ProcessResizeWindow(const til::rect* const prcClientNew, const til::rect* const prcClientOld); - void SetViewportSize(const til::size* const pcoordSize); - - // Forwarders to Window if we're the active buffer. - [[nodiscard]] NTSTATUS SetViewportOrigin(const bool fAbsolute, const til::point coordWindowOrigin, const bool updateBottom); - - bool SendNotifyBeep() const; - bool PostUpdateWindowSize() const; - - // TODO: MSFT 9355062 these methods should probably be a part of construction/destruction. http://osgvsowi/9355062 - static void s_InsertScreenBuffer(_In_ SCREEN_INFORMATION* const pScreenInfo); - static void s_RemoveScreenBuffer(_In_ SCREEN_INFORMATION* const pScreenInfo); - - TextBufferCellIterator GetCellDataAt(const til::point at) const; - TextBufferCellIterator GetCellLineDataAt(const til::point at) const; - TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const; - TextBufferTextIterator GetTextDataAt(const til::point at) const; - TextBufferTextIterator GetTextLineDataAt(const til::point at) const; - TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const; - - OutputCellIterator Write(const OutputCellIterator it); - - OutputCellIterator Write(const OutputCellIterator it, - const til::point target, - const std::optional wrap = true); - - OutputCellIterator WriteRect(const OutputCellIterator it, - const Microsoft::Console::Types::Viewport viewport); - - void WriteRect(const OutputCellRect& data, - const til::point location); - - void ClearTextData(); - - std::pair GetWordBoundary(const til::point position) const; - - TextBuffer& GetTextBuffer() noexcept; - const TextBuffer& GetTextBuffer() const noexcept; + ~SCREEN_INFORMATION() override; #pragma region IIoProvider SCREEN_INFORMATION& GetActiveOutputBuffer() override; @@ -166,129 +65,162 @@ public: InputBuffer* const GetActiveInputBuffer() const override; #pragma endregion - DWORD OutputMode{ ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT }; + // NOTE: If your method has 200 chars worth of parameters, and it's hard to read + // without wrapping, chance is you're doing it wrong. This is also true here. + // Should have been a default constructor + setters / builder pattern. + // GetScreenBufferInformation could return a struct. And so on. - short WheelDelta{ 0 }; - short HWheelDelta{ 0 }; - -private: - std::unique_ptr _textBuffer{ nullptr }; - -public: - SCREEN_INFORMATION* Next{ nullptr }; - BYTE WriteConsoleDbcsLeadByte[2]{ 0, 0 }; - BYTE FillOutDbcsLeadChar{ 0 }; - - UINT ScrollScale{ 1u }; + // Creation + [[nodiscard]] static NTSTATUS CreateInstance(til::size windowSize, FontInfo fontInfo, til::size screenBufferSize, TextAttribute defaultAttributes, TextAttribute popupAttributes, UINT cursorSize, SCREEN_INFORMATION** screen); + static void s_InsertScreenBuffer(SCREEN_INFORMATION* screenInfo); + static void s_RemoveScreenBuffer(SCREEN_INFORMATION* screenInfo); + // Buffer + TextBuffer& GetTextBuffer() noexcept; + const TextBuffer& GetTextBuffer() const noexcept; bool IsActiveScreenBuffer() const; - - const Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() const; - Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine(); - - void SetCursorInformation(const ULONG Size, - const bool Visible) noexcept; - - void SetCursorType(const CursorType Type, const bool setMain = false) noexcept; - - void SetCursorDBMode(const bool DoubleCursor); - [[nodiscard]] NTSTATUS SetCursorPosition(til::point Position); - + [[nodiscard]] NTSTATUS ResizeScreenBuffer(til::size newScreenSize, bool doScrollBarUpdate); + [[nodiscard]] NTSTATUS ResizeWithReflow(til::size newScreenSize); + [[nodiscard]] NTSTATUS ResizeTraditional(til::size newScreenSize); [[nodiscard]] NTSTATUS UseAlternateScreenBuffer(const TextAttribute& initAttributes); void UseMainScreenBuffer(); - SCREEN_INFORMATION& GetMainBuffer(); const SCREEN_INFORMATION& GetMainBuffer() const; const SCREEN_INFORMATION* GetAltBuffer() const noexcept; SCREEN_INFORMATION& GetActiveBuffer(); const SCREEN_INFORMATION& GetActiveBuffer() const; - const TextAttribute& GetAttributes() const noexcept; const TextAttribute& GetPopupAttributes() const noexcept; - void SetAttributes(const TextAttribute& attributes); void SetPopupAttributes(const TextAttribute& popupAttributes); - void SetDefaultAttributes(const TextAttribute& attributes, - const TextAttribute& popupAttributes); + void SetDefaultAttributes(const TextAttribute& attributes, const TextAttribute& popupAttributes); + void ProcessResizeWindow(const til::rect* clientNew, const til::rect* clientOld); - void UpdateBottom(); + // Cursor + [[nodiscard]] NTSTATUS SetCursorPosition(til::point Position); + void MakeCurrentCursorVisible(); + void MakeCursorVisible(til::point position); + void SnapOnInput(WORD vkey); + SnapOnScopeExit SnapOnOutput() noexcept; + void SetCursorInformation(ULONG size, bool visible) noexcept; + void SetCursorType(CursorType type, bool setMain = false) noexcept; + void SetCursorDBMode(bool doubleCursor); + // I/O + const Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() const; + Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine(); + TextBufferCellIterator GetCellDataAt(til::point at) const; + TextBufferCellIterator GetCellLineDataAt(til::point at) const; + TextBufferCellIterator GetCellDataAt(til::point at, Microsoft::Console::Types::Viewport limit) const; + TextBufferTextIterator GetTextDataAt(til::point at) const; + TextBufferTextIterator GetTextLineDataAt(til::point at) const; + TextBufferTextIterator GetTextDataAt(til::point at, Microsoft::Console::Types::Viewport limit) const; + OutputCellIterator Write(OutputCellIterator it); + OutputCellIterator Write(OutputCellIterator it, til::point target, std::optional wrap = true); + OutputCellIterator WriteRect(OutputCellIterator it, Microsoft::Console::Types::Viewport viewport); + void WriteRect(const OutputCellRect& data, til::point location); + void ClearTextData(); + + // Rendering / Viewport FontInfo& GetCurrentFont() noexcept; const FontInfo& GetCurrentFont() const noexcept; - FontInfoDesired& GetDesiredFont() noexcept; const FontInfoDesired& GetDesiredFont() const noexcept; + til::size GetScreenFontSize() const; + void UpdateFont(const FontInfo* newFont); + void RefreshFontWithRenderer(); + [[nodiscard]] NTSTATUS SetViewportOrigin(bool absolute, til::point coordWindowOrigin, bool updateBottom); + const Microsoft::Console::Types::Viewport& GetViewport() const noexcept; + void SetViewport(const Microsoft::Console::Types::Viewport& newViewport, bool updateBottom); + void SetViewportSize(const til::size* size); + void UpdateBottom(); + Microsoft::Console::Types::Viewport GetVirtualViewport() const noexcept; + Microsoft::Console::Types::Viewport GetVtPageArea() const noexcept; - [[nodiscard]] NTSTATUS ResizeWithReflow(const til::size coordnewScreenSize); - [[nodiscard]] NTSTATUS ResizeTraditional(const til::size coordNewScreenSize); + // Windowing + til::size GetScrollBarSizesInCharacters() const; + void UpdateScrollBars(); + ScrollBarState FetchScrollBarState(); + bool IsMaximizedBoth() const; + bool IsMaximizedX() const; + bool IsMaximizedY() const; + bool PostUpdateWindowSize() const; + // General Information + void GetScreenBufferInformation(til::size* size, til::point* cursorPosition, til::inclusive_rect* window, PWORD attributes, til::size* maximumWindowSize, PWORD popupAttributes, LPCOLORREF colorTable) const; + void GetRequiredConsoleSizeInPixels(til::size* requiredSize) const; + til::size GetMinWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const; + til::size GetMaxWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const; + til::size GetLargestWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const; + + // Helpers + void ClipToScreenBuffer(til::inclusive_rect* clip) const; + std::pair GetWordBoundary(til::point position) const; + Microsoft::Console::Types::Viewport GetBufferSize() const; + Microsoft::Console::Types::Viewport GetTerminalBufferSize() const; + bool SendNotifyBeep() const; bool ConptyCursorPositionMayBeWrong() const noexcept; void SetConptyCursorPositionMayBeWrong() noexcept; void ResetConptyCursorPositionMayBeWrong() noexcept; void WaitForConptyCursorPositionToBeSynchronized() noexcept; + DWORD OutputMode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + short WheelDelta = 0; + short HWheelDelta = 0; + SCREEN_INFORMATION* Next = nullptr; + BYTE WriteConsoleDbcsLeadByte[2] = { 0, 0 }; + BYTE FillOutDbcsLeadChar = 0; + UINT ScrollScale = 1; + private: - SCREEN_INFORMATION(_In_ Microsoft::Console::Interactivity::IWindowMetrics* pMetrics, - const TextAttribute popupAttributes, - const FontInfo fontInfo); - - Microsoft::Console::Interactivity::IWindowMetrics* _pConsoleWindowMetrics; - - [[nodiscard]] HRESULT _AdjustScreenBufferHelper(const til::rect* const prcClientNew, - const til::size coordBufferOld, - _Out_ til::size* const pcoordClientNewCharacters); - [[nodiscard]] HRESULT _AdjustScreenBuffer(const til::rect* const prcClientNew); - void _CalculateViewportSize(const til::rect* const prcClientArea, _Out_ til::size* const pcoordSize); - void _AdjustViewportSize(const til::rect* const prcClientNew, const til::rect* const prcClientOld, const til::size* const pcoordSize); - void _InternalSetViewportSize(const til::size* pcoordSize, const bool fResizeFromTop, const bool fResizeFromLeft); - void _makeCursorVisible(); - - static void s_CalculateScrollbarVisibility(const til::rect* const prcClientArea, - const til::size* const pcoordBufferSize, - const til::size* const pcoordFontSize, - _Out_ bool* const pfIsHorizontalVisible, - _Out_ bool* const pfIsVerticalVisible); + SCREEN_INFORMATION(Microsoft::Console::Interactivity::IWindowMetrics* metrics, TextAttribute popupAttributes, FontInfo fontInfo); + // Construction [[nodiscard]] NTSTATUS _InitializeOutputStateMachine(); void _FreeOutputStateMachine(); - [[nodiscard]] NTSTATUS _CreateAltBuffer(const TextAttribute& initAttributes, - _Out_ SCREEN_INFORMATION** const ppsiNewScreenBuffer); - + // Buffer + [[nodiscard]] HRESULT _AdjustScreenBufferHelper(const til::rect* clientNew, til::size bufferOld, til::size* clientNewCharacters); + [[nodiscard]] HRESULT _AdjustScreenBuffer(const til::rect* clientNew); + [[nodiscard]] NTSTATUS _CreateAltBuffer(const TextAttribute& initAttributes, SCREEN_INFORMATION** newScreenBuffer); bool _IsAltBuffer() const; bool _IsInPtyMode() const; bool _IsInVTMode() const; + // Cursor + void _makeCursorVisible(); + + // Rendering / Viewport + void _CalculateViewportSize(const til::rect* clientArea, til::size* size); + void _AdjustViewportSize(const til::rect* clientNew, const til::rect* clientOld, const til::size* size); + void _InternalSetViewportSize(const til::size* size, bool resizeFromTop, bool resizeFromLeft); + + // Windowing + static void s_CalculateScrollbarVisibility(const til::rect* clientArea, const til::size* bufferSize, const til::size* fontSize, bool* horizontalVisible, bool* verticalVisible); + static void _handleDeferredResize(SCREEN_INFORMATION& siMain); + + Microsoft::Console::Interactivity::IWindowMetrics* _pConsoleWindowMetrics; + std::unique_ptr _textBuffer{ nullptr }; ConhostInternalGetSet _api{ *this }; - - std::shared_ptr _stateMachine{ nullptr }; - + std::shared_ptr _stateMachine; // Specifies which coordinates of the screen buffer are visible in the // window client (the "viewport" into the buffer) Microsoft::Console::Types::Viewport _viewport; - - SCREEN_INFORMATION* _psiAlternateBuffer{ nullptr }; // The VT "Alternate" screen buffer. - SCREEN_INFORMATION* _psiMainBuffer{ nullptr }; // A pointer to the main buffer, if this is the alternate buffer. - - til::rect _rcAltSavedClientNew{}; - til::rect _rcAltSavedClientOld{}; - bool _fAltWindowChanged{ false }; - + SCREEN_INFORMATION* _psiAlternateBuffer = nullptr; // The VT "Alternate" screen buffer. + SCREEN_INFORMATION* _psiMainBuffer = nullptr; // A pointer to the main buffer, if this is the alternate buffer. + til::rect _rcAltSavedClientNew; + til::rect _rcAltSavedClientOld; + bool _fAltWindowChanged = false; TextAttribute _PopupAttributes; - FontInfo _currentFont; FontInfoDesired _desiredFont; - // Tracks the last virtual position the viewport was at. This is not // affected by the user scrolling the viewport, only when API calls cause // the viewport to move (SetBufferInfo, WriteConsole, etc) - til::CoordType _virtualBottom{ 0 }; - - std::optional _deferredPtyResize{ std::nullopt }; + til::CoordType _virtualBottom = 0; + std::optional _deferredPtyResize; std::atomic _conptyCursorPositionMayBeWrong = false; - static void _handleDeferredResize(SCREEN_INFORMATION& siMain); - #ifdef UNIT_TESTING friend class TextBufferIteratorTests; friend class ScreenBufferTests;