From a69ce89712bc79e93820c5864dedacd48bad9ce6 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 12 May 2022 21:18:40 +0100 Subject: [PATCH] Add support for the DECAC escape sequence (#13058) The `DECAC` (Assign Colors) escape sequence controls which color table entries are associated with the default foreground and background colors. This is how you would change the default colors on the the original DEC VT525 terminals. But `DECAC` also allows you to assign the color table entries for the "window frame", which in our case is mapped to the tab color (just the background for now). So this now gives us a way to control the tab color via an escape sequence as well. DETAILS ------- The way this works is there are now two new entries in the color table for the frame colors, and two new aliases in the color alias table that are mapped to those color table entries. As previously mentioned, only the background is used for now. By default, the colors are set to `INVALID_COLOR`, which indicates that the system colors should be used. But if the user has set a `tabColor` property in their profile, the frame background will be initialized with that value instead. And note that some of the existing color table entries are now renumbered for compatibility with XTerm, which uses entries 256 to 260 for special colors which we don't yet support. Our default colors are now at 261 and 262, the frame colors are 263 and 264, and the cursor color is 265. So at runtime, you can change the tab color programmatically by setting the color table entry at index 262 using `OSC 4` (assuming you need a specific RGB value). Otherwise if you just want to set the tab color to an existing color index, you can use `DECAC 2`. You can even make the tab color automatically match background color by mapping the frame background alias to the color table entry for the default background, using `DECAC 2;261;262` (technically this is mapping both the the foreground and background). This PR doesn't include support for querying the color mapping with `DECRQSS`, and doesn't support resetting the colors with `RIS`, but hopefully those can be figured out in a future PR - there are some complications that'll need to be resolved first. ## Validation Steps Performed I've added a basic unit test that confirms the `DECAC` escape sequence updates the color aliases in the render settings as expected. I've also manually confirmed that the tab color in Windows Terminal is updated by `DECAC 2`, and the default colors are updated in both conhost and WT using `DECAC 1`. Closes #6574 --- src/buffer/out/TextColor.h | 13 ++++-- src/cascadia/TerminalControl/ControlCore.cpp | 27 ++++-------- src/cascadia/TerminalControl/ControlCore.h | 2 +- src/cascadia/TerminalCore/Terminal.cpp | 26 ++++++------ src/cascadia/TerminalCore/Terminal.hpp | 3 -- src/host/ut_host/ScreenBufferTests.cpp | 38 +++++++++++++++++ src/renderer/base/RenderSettings.cpp | 9 +++- src/renderer/base/renderer.cpp | 19 ++++++++- src/renderer/base/renderer.hpp | 4 +- src/terminal/adapter/DispatchTypes.hpp | 6 +++ src/terminal/adapter/ITermDispatch.hpp | 1 + src/terminal/adapter/adaptDispatch.cpp | 42 ++++++++++++++++++- src/terminal/adapter/adaptDispatch.hpp | 1 + src/terminal/adapter/termDispatch.hpp | 1 + .../parser/OutputStateMachineEngine.cpp | 7 ++-- .../parser/OutputStateMachineEngine.hpp | 1 + src/terminal/parser/telemetry.cpp | 1 + src/terminal/parser/telemetry.hpp | 1 + 18 files changed, 155 insertions(+), 47 deletions(-) diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index c521ab4cab4..b975028760c 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -49,6 +49,8 @@ enum class ColorAlias : size_t { DefaultForeground, DefaultBackground, + FrameForeground, + FrameBackground, ENUM_COUNT // must be the last element in the enum class }; @@ -72,10 +74,13 @@ struct TextColor static constexpr BYTE BRIGHT_CYAN = 14; static constexpr BYTE BRIGHT_WHITE = 15; - static constexpr size_t DEFAULT_FOREGROUND = 256; - static constexpr size_t DEFAULT_BACKGROUND = 257; - static constexpr size_t CURSOR_COLOR = 258; - static constexpr size_t TABLE_SIZE = 259; + // Entries 256 to 260 are reserved for XTerm compatibility. + static constexpr size_t DEFAULT_FOREGROUND = 261; + static constexpr size_t DEFAULT_BACKGROUND = 262; + static constexpr size_t FRAME_FOREGROUND = 263; + static constexpr size_t FRAME_BACKGROUND = 264; + static constexpr size_t CURSOR_COLOR = 265; + static constexpr size_t TABLE_SIZE = 266; constexpr TextColor() noexcept : _meta{ ColorType::IsDefault }, diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index be5e7a70c1a..82d2a69224c 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -93,9 +93,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation auto pfnTitleChanged = std::bind(&ControlCore::_terminalTitleChanged, this, std::placeholders::_1); _terminal->SetTitleChangedCallback(pfnTitleChanged); - auto pfnTabColorChanged = std::bind(&ControlCore::_terminalTabColorChanged, this, std::placeholders::_1); - _terminal->SetTabColorChangedCallback(pfnTabColorChanged); - auto pfnScrollPositionChanged = std::bind(&ControlCore::_terminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); _terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged); @@ -126,6 +123,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread)); _renderer->SetBackgroundColorChangedCallback([this]() { _rendererBackgroundColorChanged(); }); + _renderer->SetFrameColorChangedCallback([this]() { _rendererTabColorChanged(); }); _renderer->SetRendererEnteredErrorStateCallback([weakThis = get_weak()]() { if (auto strongThis{ weakThis.get() }) @@ -647,6 +645,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Inform the renderer of our opacity _renderEngine->EnableTransparentBackground(_isBackgroundTransparent()); + // Trigger a redraw to repaint the window background and tab colors. + _renderer->TriggerRedrawAll(true, true); + _updateAntiAliasingMode(); if (sizeChanged) @@ -1144,21 +1145,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation _TitleChangedHandlers(*this, winrt::make(winrt::hstring{ wstr })); } - // Method Description: - // - Called for the Terminal's TabColorChanged callback. This will re-raise - // a new winrt TypedEvent that can be listened to. - // - The listeners to this event will re-query the control for the current - // value of TabColor(). - // Arguments: - // - - // Return Value: - // - - void ControlCore::_terminalTabColorChanged(const std::optional /*color*/) - { - // Raise a TabColorChanged event - _TabColorChangedHandlers(*this, nullptr); - } - // Method Description: // - Update the position and size of the scrollbar to match the given // viewport top, viewport height, and buffer size. @@ -1356,6 +1342,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation _BackgroundColorChangedHandlers(*this, nullptr); } + void ControlCore::_rendererTabColorChanged() + { + _TabColorChangedHandlers(*this, nullptr); + } + void ControlCore::BlinkAttributeTick() { auto lock = _terminal->LockForWriting(); diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 1a8b744cb7f..b235a93fc0b 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -265,7 +265,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation void _terminalCopyToClipboard(std::wstring_view wstr); void _terminalWarningBell(); void _terminalTitleChanged(std::wstring_view wstr); - void _terminalTabColorChanged(const std::optional color); void _terminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize); @@ -278,6 +277,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void _rendererWarning(const HRESULT hr); void _renderEngineSwapChainChanged(); void _rendererBackgroundColorChanged(); + void _rendererTabColorChanged(); #pragma endregion void _raiseReadOnlyWarning(); diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 648d7fff902..e18be09b270 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -125,11 +125,11 @@ void Terminal::UpdateSettings(ICoreSettings settings) if (settings.TabColor() == nullptr) { - _tabColor = std::nullopt; + _renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, INVALID_COLOR); } else { - _tabColor = settings.TabColor().Value(); + _renderSettings.SetColorTableEntry(TextColor::FRAME_BACKGROUND, til::color{ settings.TabColor().Value() }); } if (!_startingTabColor && settings.StartingTabColor()) @@ -137,11 +137,6 @@ void Terminal::UpdateSettings(ICoreSettings settings) _startingTabColor = settings.StartingTabColor().Value(); } - if (_pfnTabColorChanged) - { - _pfnTabColorChanged(GetTabColor()); - } - // TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we // have a smaller scrollback. We should do this carefully - if the new buffer // size is smaller than where the mutable viewport currently is, we'll want @@ -1272,11 +1267,6 @@ void Terminal::SetTitleChangedCallback(std::function pf _pfnTitleChanged.swap(pfn); } -void Terminal::SetTabColorChangedCallback(std::function)> pfn) noexcept -{ - _pfnTabColorChanged.swap(pfn); -} - void Terminal::SetCopyToClipboardCallback(std::function pfn) noexcept { _pfnCopyToClipboard.swap(pfn); @@ -1357,10 +1347,18 @@ void Terminal::ClearPatternTree() noexcept // Method Description: // - Returns the tab color -// If the starting color exits, it's value is preferred +// If the starting color exists, its value is preferred const std::optional Terminal::GetTabColor() const noexcept { - return _startingTabColor.has_value() ? _startingTabColor : _tabColor; + if (_startingTabColor.has_value()) + { + return _startingTabColor; + } + else + { + const auto tabColor = _renderSettings.GetColorAlias(ColorAlias::FrameBackground); + return tabColor == INVALID_COLOR ? std::nullopt : std::optional{ tabColor }; + } } // Method Description: diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index e89e9167b47..677a0501e89 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -196,7 +196,6 @@ class Microsoft::Terminal::Core::Terminal final : void SetWriteInputCallback(std::function pfn) noexcept; void SetWarningBellCallback(std::function pfn) noexcept; void SetTitleChangedCallback(std::function pfn) noexcept; - void SetTabColorChangedCallback(std::function)> pfn) noexcept; void SetCopyToClipboardCallback(std::function pfn) noexcept; void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetCursorPositionChangedCallback(std::function pfn) noexcept; @@ -267,7 +266,6 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnScrollPositionChanged; std::function _pfnCursorPositionChanged; - std::function)> _pfnTabColorChanged; std::function _pfnTaskbarProgressChanged; std::function _pfnShowWindowChanged; @@ -277,7 +275,6 @@ class Microsoft::Terminal::Core::Terminal final : std::optional _title; std::wstring _startingTitle; - std::optional _tabColor; std::optional _startingTabColor; CursorType _defaultCursorShape; diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 2bb59a62c77..2e2d2bcb1c1 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -171,6 +171,8 @@ class ScreenBufferTests TEST_METHOD(SetDefaultBackgroundColor); + TEST_METHOD(AssignColorAliases); + TEST_METHOD(DeleteCharsNearEndOfLine); TEST_METHOD(DeleteCharsNearEndOfLineSimpleFirstCase); TEST_METHOD(DeleteCharsNearEndOfLineSimpleSecondCase); @@ -3005,6 +3007,42 @@ void ScreenBufferTests::SetDefaultBackgroundColor() VERIFY_ARE_EQUAL(originalColor, newColor); } +void ScreenBufferTests::AssignColorAliases() +{ + auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + auto& stateMachine = gci.GetActiveOutputBuffer().GetStateMachine(); + auto& renderSettings = gci.GetRenderSettings(); + + const auto defaultFg = renderSettings.GetColorAliasIndex(ColorAlias::DefaultForeground); + const auto defaultBg = renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground); + const auto frameFg = renderSettings.GetColorAliasIndex(ColorAlias::FrameForeground); + const auto frameBg = renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground); + + auto resetAliases = wil::scope_exit([&] { + renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, defaultFg); + renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, defaultBg); + renderSettings.SetColorAliasIndex(ColorAlias::FrameForeground, frameFg); + renderSettings.SetColorAliasIndex(ColorAlias::FrameBackground, frameBg); + }); + + Log::Comment(L"Test invalid item color assignment"); + stateMachine.ProcessString(L"\033[0;12;34,|"); + VERIFY_ARE_EQUAL(defaultFg, renderSettings.GetColorAliasIndex(ColorAlias::DefaultForeground)); + VERIFY_ARE_EQUAL(defaultBg, renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground)); + VERIFY_ARE_EQUAL(frameFg, renderSettings.GetColorAliasIndex(ColorAlias::FrameForeground)); + VERIFY_ARE_EQUAL(frameBg, renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground)); + + Log::Comment(L"Test normal text color assignment"); + stateMachine.ProcessString(L"\033[1;23;45,|"); + VERIFY_ARE_EQUAL(23u, renderSettings.GetColorAliasIndex(ColorAlias::DefaultForeground)); + VERIFY_ARE_EQUAL(45u, renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground)); + + Log::Comment(L"Test window frame color assignment"); + stateMachine.ProcessString(L"\033[2;34;56,|"); + VERIFY_ARE_EQUAL(34u, renderSettings.GetColorAliasIndex(ColorAlias::FrameForeground)); + VERIFY_ARE_EQUAL(56u, renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground)); +} + void ScreenBufferTests::DeleteCharsNearEndOfLine() { // Created for MSFT:19888564. diff --git a/src/renderer/base/RenderSettings.cpp b/src/renderer/base/RenderSettings.cpp index e889adccbf7..fab1f7dc10e 100644 --- a/src/renderer/base/RenderSettings.cpp +++ b/src/renderer/base/RenderSettings.cpp @@ -20,10 +20,14 @@ RenderSettings::RenderSettings() noexcept SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); + SetColorTableEntry(TextColor::FRAME_FOREGROUND, INVALID_COLOR); + SetColorTableEntry(TextColor::FRAME_BACKGROUND, INVALID_COLOR); SetColorTableEntry(TextColor::CURSOR_COLOR, INVALID_COLOR); SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DARK_WHITE); SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DARK_BLACK); + SetColorAliasIndex(ColorAlias::FrameForeground, TextColor::FRAME_FOREGROUND); + SetColorAliasIndex(ColorAlias::FrameBackground, TextColor::FRAME_BACKGROUND); } // Routine Description: @@ -149,7 +153,10 @@ COLORREF RenderSettings::GetColorAlias(const ColorAlias alias) const // - tableIndex - The new position of the alias in the color table. void RenderSettings::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept { - gsl::at(_colorAliasIndices, static_cast(alias)) = tableIndex; + if (tableIndex < TextColor::TABLE_SIZE) + { + gsl::at(_colorAliasIndices, static_cast(alias)) = tableIndex; + } } // Routine Description: diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 73991da11e9..b75b55de0ba 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -299,9 +299,10 @@ void Renderer::TriggerRedrawCursor(const COORD* const pcoord) // - NOTE: Use sparingly. Try to reduce the refresh region where possible. Only use when a global state change has occurred. // Arguments: // - backgroundChanged - Set to true if the background color has changed. +// - frameChanged - Set to true if the frame colors have changed. // Return Value: // - -void Renderer::TriggerRedrawAll(const bool backgroundChanged) +void Renderer::TriggerRedrawAll(const bool backgroundChanged, const bool frameChanged) { FOREACH_ENGINE(pEngine) { @@ -314,6 +315,11 @@ void Renderer::TriggerRedrawAll(const bool backgroundChanged) { _pfnBackgroundColorChanged(); } + + if (frameChanged && _pfnFrameColorChanged) + { + _pfnFrameColorChanged(); + } } // Method Description: @@ -1348,6 +1354,17 @@ void Renderer::SetBackgroundColorChangedCallback(std::function pfn) _pfnBackgroundColorChanged = std::move(pfn); } +// Method Description: +// - Registers a callback for when the frame colors have changed +// Arguments: +// - pfn: the callback +// Return Value: +// - +void Renderer::SetFrameColorChangedCallback(std::function pfn) +{ + _pfnFrameColorChanged = std::move(pfn); +} + // Method Description: // - Registers a callback that will be called when this renderer gives up. // An application consuming a renderer can use this to display auxiliary Retry UI diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index ff9bcebd943..009f3a954f9 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -52,7 +52,7 @@ namespace Microsoft::Console::Render void TriggerRedraw(const Microsoft::Console::Types::Viewport& region); void TriggerRedraw(const COORD* const pcoord); void TriggerRedrawCursor(const COORD* const pcoord); - void TriggerRedrawAll(const bool backgroundChanged = false); + void TriggerRedrawAll(const bool backgroundChanged = false, const bool frameChanged = false); void TriggerTeardown() noexcept; void TriggerSelection(); @@ -85,6 +85,7 @@ namespace Microsoft::Console::Render void AddRenderEngine(_In_ IRenderEngine* const pEngine); void SetBackgroundColorChangedCallback(std::function pfn); + void SetFrameColorChangedCallback(std::function pfn); void SetRendererEnteredErrorStateCallback(std::function pfn); void ResetErrorStateAndResume(); @@ -123,6 +124,7 @@ namespace Microsoft::Console::Render std::vector _clusterBuffer; std::vector _previousSelection; std::function _pfnBackgroundColorChanged; + std::function _pfnFrameColorChanged; std::function _pfnRendererEnteredErrorState; bool _destructing = false; bool _forceUpdateViewport = true; diff --git a/src/terminal/adapter/DispatchTypes.hpp b/src/terminal/adapter/DispatchTypes.hpp index dd35c858ad4..8a6e14d1864 100644 --- a/src/terminal/adapter/DispatchTypes.hpp +++ b/src/terminal/adapter/DispatchTypes.hpp @@ -239,6 +239,12 @@ namespace Microsoft::Console::VirtualTerminal namespace Microsoft::Console::VirtualTerminal::DispatchTypes { + enum class ColorItem : VTInt + { + NormalText = 1, + WindowFrame = 2, + }; + enum class EraseType : VTInt { ToEnd = 0, diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index 0433d9662d7..f2dcb1c2a8d 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -85,6 +85,7 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCColorTable virtual bool SetDefaultForeground(const DWORD color) = 0; // OSCDefaultForeground virtual bool SetDefaultBackground(const DWORD color) = 0; // OSCDefaultBackground + virtual bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) = 0; // DECAC virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED virtual bool EraseInLine(const DispatchTypes::EraseType eraseType) = 0; // EL diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 2dca06ebe4b..bce951e5938 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2241,9 +2241,13 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo const auto backgroundIndex = _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground); const auto backgroundChanged = (tableIndex == backgroundIndex); + // Similarly for the frame color, the tab may need to be repainted. + const auto frameIndex = _renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground); + const auto frameChanged = (tableIndex == frameIndex); + // Update the screen colors if we're not a pty // No need to force a redraw in pty mode. - _renderer.TriggerRedrawAll(backgroundChanged); + _renderer.TriggerRedrawAll(backgroundChanged, frameChanged); return true; } @@ -2271,6 +2275,42 @@ bool AdaptDispatch::SetDefaultBackground(const DWORD dwColor) return SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, dwColor); } +// Method Description: +// DECAC - Assigns the foreground and background color indexes that should be +// used for a given aspect of the user interface. +// Arguments: +// - item: The aspect of the interface that will have its colors altered. +// - fgIndex: The color table index to be used for the foreground. +// - bgIndex: The color table index to be used for the background. +// Return Value: +// True if handled successfully. False otherwise. +bool AdaptDispatch::AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) +{ + switch (item) + { + case DispatchTypes::ColorItem::NormalText: + _renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, fgIndex); + _renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, bgIndex); + break; + case DispatchTypes::ColorItem::WindowFrame: + _renderSettings.SetColorAliasIndex(ColorAlias::FrameForeground, fgIndex); + _renderSettings.SetColorAliasIndex(ColorAlias::FrameBackground, bgIndex); + break; + default: + return false; + } + + // No need to force a redraw in pty mode. + const auto inPtyMode = _api.IsConsolePty(); + if (!inPtyMode) + { + const auto backgroundChanged = item == DispatchTypes::ColorItem::NormalText; + const auto frameChanged = item == DispatchTypes::ColorItem::WindowFrame; + _renderer.TriggerRedrawAll(backgroundChanged, frameChanged); + } + return !inPtyMode; +} + //Routine Description: // Window Manipulation - Performs a variety of actions relating to the window, // such as moving the window position, resizing the window, querying diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 722645dc1a5..e132444182c 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -119,6 +119,7 @@ namespace Microsoft::Console::VirtualTerminal const DWORD color) override; // OSCColorTable bool SetDefaultForeground(const DWORD color) override; // OSCDefaultForeground bool SetDefaultBackground(const DWORD color) override; // OSCDefaultBackground + bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) override; // DECAC bool WindowManipulation(const DispatchTypes::WindowManipulationType function, const VTParameter parameter1, diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index 386d1ced717..ad724641160 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -78,6 +78,7 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCColorTable bool SetDefaultForeground(const DWORD /*color*/) override { return false; } // OSCDefaultForeground bool SetDefaultBackground(const DWORD /*color*/) override { return false; } // OSCDefaultBackground + bool AssignColor(const DispatchTypes::ColorItem /*item*/, const VTInt /*fgIndex*/, const VTInt /*bgIndex*/) override { return false; } // DECAC bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED bool EraseInLine(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // EL diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 864aa8555b5..244e7c64979 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -606,19 +606,20 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParamete success = _dispatch->SoftReset(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTR); break; - case CsiActionCodes::XT_PushSgr: case CsiActionCodes::XT_PushSgrAlias: success = _dispatch->PushGraphicsRendition(parameters); TermTelemetry::Instance().Log(TermTelemetry::Codes::XTPUSHSGR); break; - case CsiActionCodes::XT_PopSgr: case CsiActionCodes::XT_PopSgrAlias: success = _dispatch->PopGraphicsRendition(); TermTelemetry::Instance().Log(TermTelemetry::Codes::XTPOPSGR); break; - + case CsiActionCodes::DECAC_AssignColor: + success = _dispatch->AssignColor(parameters.at(0), parameters.at(1).value_or(0), parameters.at(2).value_or(0)); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECAC); + break; default: // If no functions to call, overall dispatch was a failure. success = false; diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index 8f6305bdc7c..20083b474d8 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -142,6 +142,7 @@ namespace Microsoft::Console::VirtualTerminal XT_PushSgr = VTID("#{"), XT_PopSgr = VTID("#}"), DECSCPP_SetColumnsPerPage = VTID("$|"), + DECAC_AssignColor = VTID(",|") }; enum DcsActionCodes : uint64_t diff --git a/src/terminal/parser/telemetry.cpp b/src/terminal/parser/telemetry.cpp index 831a474f1c1..a40711ef506 100644 --- a/src/terminal/parser/telemetry.cpp +++ b/src/terminal/parser/telemetry.cpp @@ -280,6 +280,7 @@ void TermTelemetry::WriteFinalTraceLog() const TraceLoggingUInt32(_uiTimesUsed[DECALN], "DECALN"), TraceLoggingUInt32(_uiTimesUsed[XTPUSHSGR], "XTPUSHSGR"), TraceLoggingUInt32(_uiTimesUsed[XTPOPSGR], "XTPOPSGR"), + TraceLoggingUInt32(_uiTimesUsed[DECAC], "DECAC"), TraceLoggingUInt32Array(_uiTimesFailed, ARRAYSIZE(_uiTimesFailed), "Failed"), TraceLoggingUInt32(_uiTimesFailedOutsideRange, "FailedOutsideRange")); } diff --git a/src/terminal/parser/telemetry.hpp b/src/terminal/parser/telemetry.hpp index 7dd58353ccf..196d13016bd 100644 --- a/src/terminal/parser/telemetry.hpp +++ b/src/terminal/parser/telemetry.hpp @@ -107,6 +107,7 @@ namespace Microsoft::Console::VirtualTerminal OSCSCB, XTPUSHSGR, XTPOPSGR, + DECAC, // Only use this last enum as a count of the number of codes. NUMBER_OF_CODES };