diff --git a/src/cascadia/TerminalControl/HwndTerminal.cpp b/src/cascadia/TerminalControl/HwndTerminal.cpp index f2465d1aa16..905de2ce988 100644 --- a/src/cascadia/TerminalControl/HwndTerminal.cpp +++ b/src/cascadia/TerminalControl/HwndTerminal.cpp @@ -891,6 +891,9 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font renderSettings.SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex)); } + // Save these values as the new default render settings. + renderSettings.SaveDefaultSettings(); + publicTerminal->_terminal->SetCursorStyle(static_cast(theme.CursorStyle)); publicTerminal->_desiredFont = { fontFamily, 0, DEFAULT_FONT_WEIGHT, static_cast(fontSize), CP_UTF8 }; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index f4abf95ab5c..126052dd701 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -101,6 +101,9 @@ void Terminal::UpdateSettings(ICoreSettings settings) GetRenderSettings().SetColorTableEntry(TextColor::FRAME_BACKGROUND, til::color{ settings.TabColor().Value() }); } + // Save the changes made above and in UpdateAppearance as the new default render settings. + GetRenderSettings().SaveDefaultSettings(); + if (!_startingTabColor && settings.StartingTabColor()) { _startingTabColor = settings.StartingTabColor().Value(); diff --git a/src/host/settings.cpp b/src/host/settings.cpp index 0df97dbd354..746bd91564f 100644 --- a/src/host/settings.cpp +++ b/src/host/settings.cpp @@ -349,6 +349,8 @@ void Settings::Validate() TextAttribute::SetLegacyDefaultAttributes(_wFillAttribute); // And calculate the position of the default colors in the color table. CalculateDefaultColorIndices(); + // We can also then save these values as the default render settings. + SaveDefaultRenderSettings(); FAIL_FAST_IF(!(_dwWindowSize.X > 0)); FAIL_FAST_IF(!(_dwWindowSize.Y > 0)); @@ -755,6 +757,11 @@ void Settings::CalculateDefaultColorIndices() noexcept _renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, backgroundAlias); } +void Settings::SaveDefaultRenderSettings() noexcept +{ + _renderSettings.SaveDefaultSettings(); +} + bool Settings::IsTerminalScrolling() const noexcept { return _TerminalScrolling; diff --git a/src/host/settings.hpp b/src/host/settings.hpp index 04b169a7b76..240872f9ccf 100644 --- a/src/host/settings.hpp +++ b/src/host/settings.hpp @@ -172,6 +172,7 @@ class Settings void SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept; void CalculateDefaultColorIndices() noexcept; + void SaveDefaultRenderSettings() noexcept; bool IsTerminalScrolling() const noexcept; void SetTerminalScrolling(const bool terminalScrollingEnabled) noexcept; diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index f4aa82ac42b..a81d47ec931 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -16,6 +16,7 @@ #include "../interactivity/inc/ServiceLocator.hpp" #include "../../inc/conattrs.hpp" +#include "../../types/inc/colorTable.hpp" #include "../../types/inc/Viewport.hpp" #include "../../inc/TestUtils.h" @@ -2070,6 +2071,15 @@ void ScreenBufferTests::VtRestoreColorTableReport() // Blue component is clamped at 100%, so 150% interpreted as 100% stateMachine.ProcessString(L"\033P2$p14;2;0;0;150\033\\"); VERIFY_ARE_EQUAL(RGB(0, 0, 255), gci.GetColorTableEntry(14)); + + Log::Comment(L"RIS restores initial Campbell color scheme"); + + stateMachine.ProcessString(L"\033c"); + for (auto i = 0; i < 16; i++) + { + const COLORREF expectedColor = Microsoft::Console::Utils::CampbellColorTable()[i]; + VERIFY_ARE_EQUAL(expectedColor, gci.GetColorTableEntry(i)); + } } void ScreenBufferTests::ResizeTraditionalDoesNotDoubleFreeAttrRows() @@ -3352,6 +3362,13 @@ void ScreenBufferTests::AssignColorAliases() stateMachine.ProcessString(L"\033[2;34;56,|"); VERIFY_ARE_EQUAL(34u, renderSettings.GetColorAliasIndex(ColorAlias::FrameForeground)); VERIFY_ARE_EQUAL(56u, renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground)); + + Log::Comment(L"Test RIS restores initial color assignments"); + stateMachine.ProcessString(L"\033c"); + 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)); } void ScreenBufferTests::DeleteCharsNearEndOfLine() diff --git a/src/interactivity/win32/menu.cpp b/src/interactivity/win32/menu.cpp index e9736728a74..e4d0ce0aea3 100644 --- a/src/interactivity/win32/menu.cpp +++ b/src/interactivity/win32/menu.cpp @@ -576,6 +576,8 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo) TextAttribute::SetLegacyDefaultAttributes(pStateInfo->ScreenAttributes); // And recalculate the position of the default colors in the color table. gci.CalculateDefaultColorIndices(); + // Then save these values as the new default render settings. + gci.SaveDefaultRenderSettings(); // Set the screen info's default text attributes to defaults - ScreenInfo.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); diff --git a/src/renderer/base/RenderSettings.cpp b/src/renderer/base/RenderSettings.cpp index f237b5d3e98..0410211143d 100644 --- a/src/renderer/base/RenderSettings.cpp +++ b/src/renderer/base/RenderSettings.cpp @@ -26,6 +26,29 @@ RenderSettings::RenderSettings() noexcept SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DARK_BLACK); SetColorAliasIndex(ColorAlias::FrameForeground, TextColor::FRAME_FOREGROUND); SetColorAliasIndex(ColorAlias::FrameBackground, TextColor::FRAME_BACKGROUND); + + SaveDefaultSettings(); +} + +// Routine Description: +// - Saves the current color table and color aliases as the default values, so +// we can later restore them when a hard reset (RIS) is requested. +void RenderSettings::SaveDefaultSettings() noexcept +{ + _defaultColorTable = _colorTable; + _defaultColorAliasIndices = _colorAliasIndices; +} + +// Routine Description: +// - Resets the render settings to their default values. which is typically +// what they were set to at startup. +void RenderSettings::RestoreDefaultSettings() noexcept +{ + _colorTable = _defaultColorTable; + _colorAliasIndices = _defaultColorAliasIndices; + // For now, DECSCNM is the only render mode we need to reset. The others are + // all user preferences that can't be changed programmatically. + _renderMode.reset(Mode::ScreenReversed); } // Routine Description: diff --git a/src/renderer/inc/RenderSettings.hpp b/src/renderer/inc/RenderSettings.hpp index 704f97d4f09..a9c370133c6 100644 --- a/src/renderer/inc/RenderSettings.hpp +++ b/src/renderer/inc/RenderSettings.hpp @@ -29,6 +29,8 @@ namespace Microsoft::Console::Render }; RenderSettings() noexcept; + void SaveDefaultSettings() noexcept; + void RestoreDefaultSettings() noexcept; void SetRenderMode(const Mode mode, const bool enabled) noexcept; bool GetRenderMode(const Mode mode) const noexcept; const std::array& GetColorTable() const noexcept; @@ -48,6 +50,8 @@ namespace Microsoft::Console::Render til::enumset _renderMode{ Mode::BlinkAllowed, Mode::IntenseIsBright }; std::array _colorTable; std::array(ColorAlias::ENUM_COUNT)> _colorAliasIndices; + std::array _defaultColorTable; + std::array(ColorAlias::ENUM_COUNT)> _defaultColorAliasIndices; size_t _blinkCycle = 0; mutable bool _blinkIsInUse = false; bool _blinkShouldBeFaint = false; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index edbda3f514a..3899c7cd84d 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -3019,8 +3019,13 @@ void AdaptDispatch::HardReset() EraseInDisplay(DispatchTypes::EraseType::All); EraseInDisplay(DispatchTypes::EraseType::Scrollback); - // Set the DECSCNM screen mode back to normal. - _renderSettings.SetRenderMode(RenderSettings::Mode::ScreenReversed, false); + // Set the color table and render modes back to their initial startup values. + _renderSettings.RestoreDefaultSettings(); + // Let the renderer know that the background and frame colors may have changed. + if (_renderer) + { + _renderer->TriggerRedrawAll(true, true); + } // Cursor to 1,1 - the Soft Reset guarantees this is absolute CursorPosition(1, 1);