diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index 3070f81697..d7e0edf761 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -82,7 +82,8 @@ public: 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; + static constexpr size_t SELECTION_BACKGROUND = 266; + static constexpr size_t TABLE_SIZE = 267; constexpr TextColor() noexcept : _meta{ ColorType::IsDefault }, diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 06d6e0478e..d8d975f667 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -349,9 +349,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, windowSize); LOG_IF_FAILED(_renderEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() })); - // Update AtlasEngine's SelectionBackground - _renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() }); - const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels); const auto width = vp.Width(); const auto height = vp.Height(); @@ -900,7 +897,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_renderEngine) { // Update AtlasEngine settings under the lock - _renderEngine->SetSelectionBackground(til::color{ newAppearance->SelectionBackground() }); _renderEngine->SetRetroTerminalEffect(newAppearance->RetroTerminalEffect()); _renderEngine->SetPixelShaderPath(newAppearance->PixelShaderPath()); _renderEngine->SetPixelShaderImagePath(newAppearance->PixelShaderImagePath()); @@ -2412,7 +2408,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto lock = _terminal->LockForWriting(); _terminal->ApplyScheme(scheme); - _renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() }); _renderer->TriggerRedrawAll(true); } diff --git a/src/cascadia/TerminalControl/HwndTerminal.cpp b/src/cascadia/TerminalControl/HwndTerminal.cpp index 4b8c345baa..f2465d1aa1 100644 --- a/src/cascadia/TerminalControl/HwndTerminal.cpp +++ b/src/cascadia/TerminalControl/HwndTerminal.cpp @@ -881,8 +881,7 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font auto& renderSettings = publicTerminal->_terminal->GetRenderSettings(); renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground); renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground); - - publicTerminal->_renderEngine->SetSelectionBackground(theme.DefaultSelectionBackground); + renderSettings.SetColorTableEntry(TextColor::SELECTION_BACKGROUND, theme.DefaultSelectionBackground); // Set the font colors for (size_t tableIndex = 0; tableIndex < 16; tableIndex++) diff --git a/src/cascadia/TerminalControl/IControlAppearance.idl b/src/cascadia/TerminalControl/IControlAppearance.idl index e8ed4daaea..098c8235fe 100644 --- a/src/cascadia/TerminalControl/IControlAppearance.idl +++ b/src/cascadia/TerminalControl/IControlAppearance.idl @@ -5,7 +5,6 @@ namespace Microsoft.Terminal.Control { interface IControlAppearance requires Microsoft.Terminal.Core.ICoreAppearance { - Microsoft.Terminal.Core.Color SelectionBackground { get; }; String BackgroundImage { get; }; Single BackgroundImageOpacity { get; }; Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode { get; }; diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index d8ad5a9f67..fa0364a322 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -115,6 +115,7 @@ namespace Microsoft.Terminal.Core { Microsoft.Terminal.Core.Color DefaultForeground; Microsoft.Terminal.Core.Color DefaultBackground; + Microsoft.Terminal.Core.Color SelectionBackground; Microsoft.Terminal.Core.Color GetColorTableEntry(Int32 index); Microsoft.Terminal.Core.Color CursorColor; CursorStyle CursorShape; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 87236331fc..b7e343998d 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -155,6 +155,8 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance) renderSettings.SetColorAlias(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND, newForegroundColor); const til::color newCursorColor{ appearance.CursorColor() }; renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, newCursorColor); + const til::color newSelectionColor{ appearance.SelectionBackground() }; + renderSettings.SetColorTableEntry(TextColor::SELECTION_BACKGROUND, newSelectionColor); for (auto i = 0; i < 16; i++) { @@ -1275,8 +1277,8 @@ Scheme Terminal::GetColorScheme() const s.Foreground = til::color{ renderSettings.GetColorAlias(ColorAlias::DefaultForeground) }; s.Background = til::color{ renderSettings.GetColorAlias(ColorAlias::DefaultBackground) }; - // SelectionBackground is stored in the ControlAppearance s.CursorColor = til::color{ renderSettings.GetColorTableEntry(TextColor::CURSOR_COLOR) }; + s.SelectionBackground = til::color{ renderSettings.GetColorTableEntry(TextColor::SELECTION_BACKGROUND) }; s.Black = til::color{ renderSettings.GetColorTableEntry(TextColor::DARK_BLACK) }; s.Red = til::color{ renderSettings.GetColorTableEntry(TextColor::DARK_RED) }; @@ -1322,6 +1324,7 @@ void Terminal::ApplyScheme(const Scheme& colorScheme) renderSettings.SetColorTableEntry(TextColor::BRIGHT_WHITE, til::color{ colorScheme.BrightWhite }); renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, til::color{ colorScheme.CursorColor }); + renderSettings.SetColorTableEntry(TextColor::SELECTION_BACKGROUND, til::color{ colorScheme.SelectionBackground }); // Tell the control that the scrollbar has somehow changed. Used as a // workaround to force the control to redraw any scrollbar marks whose color diff --git a/src/cascadia/inc/ControlProperties.h b/src/cascadia/inc/ControlProperties.h index 4698045f9e..bc5e3748b4 100644 --- a/src/cascadia/inc/ControlProperties.h +++ b/src/cascadia/inc/ControlProperties.h @@ -11,6 +11,7 @@ X(til::color, CursorColor, DEFAULT_CURSOR_COLOR) \ X(winrt::Microsoft::Terminal::Core::CursorStyle, CursorShape, winrt::Microsoft::Terminal::Core::CursorStyle::Vintage) \ X(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT) \ + X(til::color, SelectionBackground, DEFAULT_FOREGROUND) \ X(bool, IntenseIsBold) \ X(bool, IntenseIsBright, true) \ X(winrt::Microsoft::Terminal::Core::AdjustTextMode, AdjustIndistinguishableColors, winrt::Microsoft::Terminal::Core::AdjustTextMode::Never) @@ -18,7 +19,6 @@ // --------------------------- Control Appearance --------------------------- // All of these settings are defined in IControlAppearance. #define CONTROL_APPEARANCE_SETTINGS(X) \ - X(til::color, SelectionBackground, DEFAULT_FOREGROUND) \ X(float, Opacity, 1.0f) \ X(bool, UseAcrylic, false) \ X(winrt::hstring, BackgroundImage) \ diff --git a/src/renderer/atlas/AtlasEngine.api.cpp b/src/renderer/atlas/AtlasEngine.api.cpp index 6481d5b905..a80ae930ba 100644 --- a/src/renderer/atlas/AtlasEngine.api.cpp +++ b/src/renderer/atlas/AtlasEngine.api.cpp @@ -7,7 +7,6 @@ #include "Backend.h" #include "../../buffer/out/textBuffer.hpp" #include "../base/FontCache.h" -#include "../../types/inc/ColorFix.hpp" // #### NOTE #### // If you see any code in here that contains "_r." you might be seeing a race condition. @@ -425,18 +424,6 @@ void AtlasEngine::SetRetroTerminalEffect(bool enable) noexcept } } -void AtlasEngine::SetSelectionBackground(const COLORREF color) noexcept -{ - const u32 selectionColor = (color & 0xffffff) | 0xff000000; - if (_api.s->misc->selectionColor != selectionColor) - { - auto misc = _api.s.write()->misc.write(); - misc->selectionColor = selectionColor; - // Select a black or white foreground based on the perceptual lightness of the background. - misc->selectionForeground = ColorFix::GetLuminosity(selectionColor) < 0.5f ? 0xffffffff : 0xff000000; - } -} - void AtlasEngine::SetSoftwareRendering(bool enable) noexcept { if (_api.s->target->useWARP != enable) diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index 18e415a599..0de92b6237 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -315,6 +315,21 @@ CATCH_RETURN() } _api.selectionSpans = til::point_span_subspan_within_rect(info.selectionSpans, dr); + + const u32 newSelectionColor{ static_cast(info.selectionBackground) | 0xff000000 }; + if (_api.s->misc->selectionColor != newSelectionColor) + { + auto misc = _api.s.write()->misc.write(); + misc->selectionColor = newSelectionColor; + // Select a black or white foreground based on the perceptual lightness of the background. + misc->selectionForeground = ColorFix::GetLuminosity(newSelectionColor) < 0.5f ? 0xffffffff : 0xff000000; + + // We copied the selection colors into _p during StartPaint, which happened just before PrepareRenderInfo + // This keeps their generations in sync. + auto pm = _p.s.write()->misc.write(); + pm->selectionColor = misc->selectionColor; + pm->selectionForeground = misc->selectionForeground; + } } return S_OK; @@ -502,7 +517,7 @@ try // Apply the highlighting colors to the highlighted cells RETURN_IF_FAILED(_drawHighlighted(_api.searchHighlights, y, x, columnEnd, highlightFg, highlightBg)); RETURN_IF_FAILED(_drawHighlighted(_api.searchHighlightFocused, y, x, columnEnd, highlightFocusFg, highlightFocusBg)); - RETURN_IF_FAILED(_drawHighlighted(_api.selectionSpans, y, x, columnEnd, _api.s->misc->selectionForeground, _api.s->misc->selectionColor)); + RETURN_IF_FAILED(_drawHighlighted(_api.selectionSpans, y, x, columnEnd, _p.s->misc->selectionForeground, _p.s->misc->selectionColor)); _api.lastPaintBufferLineCoord = { x, y }; return S_OK; diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index b20bd04f4c..af77dcfe69 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -71,7 +71,6 @@ namespace Microsoft::Console::Render::Atlas void SetPixelShaderPath(std::wstring_view value) noexcept; void SetPixelShaderImagePath(std::wstring_view value) noexcept; void SetRetroTerminalEffect(bool enable) noexcept; - void SetSelectionBackground(COLORREF color) noexcept; void SetSoftwareRendering(bool enable) noexcept; void SetDisablePartialInvalidation(bool enable) noexcept; void SetGraphicsAPI(GraphicsAPI graphicsAPI) noexcept; diff --git a/src/renderer/base/RenderSettings.cpp b/src/renderer/base/RenderSettings.cpp index db9afca8dc..f237b5d3e9 100644 --- a/src/renderer/base/RenderSettings.cpp +++ b/src/renderer/base/RenderSettings.cpp @@ -20,6 +20,7 @@ RenderSettings::RenderSettings() noexcept SetColorTableEntry(TextColor::FRAME_FOREGROUND, INVALID_COLOR); SetColorTableEntry(TextColor::FRAME_BACKGROUND, INVALID_COLOR); SetColorTableEntry(TextColor::CURSOR_COLOR, INVALID_COLOR); + SetColorTableEntry(TextColor::SELECTION_BACKGROUND, INVALID_COLOR); SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DARK_WHITE); SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DARK_BLACK); diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 33892087e4..c44216ac47 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -1276,6 +1276,7 @@ void Renderer::_PaintCursor(_In_ IRenderEngine* const pEngine) info.searchHighlights = _pData->GetSearchHighlights(); info.searchHighlightFocused = _pData->GetSearchHighlightFocused(); info.selectionSpans = _pData->GetSelectionSpans(); + info.selectionBackground = _renderSettings.GetColorTableEntry(TextColor::SELECTION_BACKGROUND); return pEngine->PrepareRenderInfo(std::move(info)); } diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index d0a4f0f5d8..a2cc944f29 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -33,6 +33,7 @@ namespace Microsoft::Console::Render std::span searchHighlights; const til::point_span* searchHighlightFocused; std::span selectionSpans; + til::color selectionBackground; }; enum class GridLines diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index ebde16938a..a02895a199 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -32,7 +32,7 @@ static constexpr std::array XtermResourceColor /* 14 */ { -1, -1 }, /* 15 */ { -1, -1 }, /* 16 */ { -1, -1 }, - /* 17 */ { -1, -1 }, + /* 17 */ { TextColor::SELECTION_BACKGROUND, -1 }, /* 18 */ { -1, -1 }, /* 19 */ { -1, -1 }, } }; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 874f382642..4058df7ff2 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -804,6 +804,7 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s case OscActionCodes::SetForegroundColor: case OscActionCodes::SetBackgroundColor: case OscActionCodes::SetCursorColor: + case OscActionCodes::SetHighlightColor: { std::vector colors; success = _GetOscSetColor(string, colors); diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index c661bcecc6..d616294c47 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -213,6 +213,7 @@ namespace Microsoft::Console::VirtualTerminal SetForegroundColor = 10, SetBackgroundColor = 11, SetCursorColor = 12, + SetHighlightColor = 17, DECSWT_SetWindowTitle = 21, SetClipboard = 52, ResetForegroundColor = 110, // Not implemented