Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for OSC 10 and 11 to set the default colors #891

Merged
merged 11 commits into from
May 24, 2019
81 changes: 49 additions & 32 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,46 +158,16 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// - Style our UI elements based on the values in our _settings, and set up
// other control-specific settings. This method will be called whenever
// the settings are reloaded.
// * Sets up the background of the control with the provided BG color,
// acrylic or not, and if acrylic, then uses the opacity from _settings.
// * Calls _BackgroundColorChanged to style the background of the control
// - Core settings will be passed to the terminal in _InitializeTerminal
// Arguments:
// - <none>
// Return Value:
// - <none>
void TermControl::_ApplyUISettings()
{
winrt::Windows::UI::Color bgColor{};
uint32_t bg = _settings.DefaultBackground();
const auto R = GetRValue(bg);
const auto G = GetGValue(bg);
const auto B = GetBValue(bg);
bgColor.R = R;
bgColor.G = G;
bgColor.B = B;
bgColor.A = 255;

if (_settings.UseAcrylic())
{
Media::AcrylicBrush acrylic{};
acrylic.BackgroundSource(Media::AcrylicBackgroundSource::HostBackdrop);
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
acrylic.TintOpacity(_settings.TintOpacity());
_root.Background(acrylic);

// If we're acrylic, we want to make sure that the default BG color
// is transparent, so we can see the acrylic effect on text with the
// default BG color.
_settings.DefaultBackground(ARGB(0, R, G, B));
}
else
{
Media::SolidColorBrush solidColor{};
solidColor.Color(bgColor);
_root.Background(solidColor);
_settings.DefaultBackground(RGB(R, G, B));
}
_BackgroundColorChanged(bg);

// Apply padding to the root Grid
auto thickness = _ParseThicknessFromPadding(_settings.Padding());
Expand All @@ -216,6 +186,50 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_desiredFont = { _actualFont };
}

// Method Description:
// - Style the background of the control with the provided background color
// - Respects the settings for acrylic and opacity from _settings
// Arguments:
// - color: The background color to use as a uint32 (aka DWORD COLORREF)
// Return Value:
// - <none>
void TermControl::_BackgroundColorChanged(const uint32_t color)
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
_root.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, color]() {
const auto R = GetRValue(color);
const auto G = GetGValue(color);
const auto B = GetBValue(color);

winrt::Windows::UI::Color bgColor{};
bgColor.R = R;
bgColor.G = G;
bgColor.B = B;
bgColor.A = 255;

if (_settings.UseAcrylic())
{
Media::AcrylicBrush acrylic{};
acrylic.BackgroundSource(Media::AcrylicBackgroundSource::HostBackdrop);
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
acrylic.TintOpacity(_settings.TintOpacity());
_root.Background(acrylic);

// If we're acrylic, we want to make sure that the default BG color
// is transparent, so we can see the acrylic effect on text with the
// default BG color.
_settings.DefaultBackground(ARGB(0, R, G, B));
}
else
{
Media::SolidColorBrush solidColor{};
solidColor.Color(bgColor);
_root.Background(solidColor);
_settings.DefaultBackground(RGB(R, G, B));
}
});
}

// Method Description:
// - Create a connection based on the values in our settings object.
// * Gets the commandline and working directory out of the _settings and
Expand Down Expand Up @@ -406,6 +420,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1);
_terminal->SetTitleChangedCallback(pfnTitleChanged);

auto pfnBackgroundColorChanged = std::bind(&TermControl::_BackgroundColorChanged, this, std::placeholders::_1);
_terminal->SetBackgroundCallback(pfnBackgroundColorChanged);

auto pfnScrollPositionChanged = std::bind(&TermControl::_TerminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
_terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged);

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation

void _Create();
void _ApplyUISettings();
void _BackgroundColorChanged(const uint32_t color);
void _ApplyConnectionSettings();
void _InitializeTerminal();
void _UpdateFont();
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalCore/ITerminalApi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@ namespace Microsoft::Terminal::Core
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) = 0;

virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0;

virtual bool SetDefaultForeground(const DWORD dwColor) = 0;
virtual bool SetDefaultBackground(const DWORD dwColor) = 0;
};
}
9 changes: 9 additions & 0 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,15 @@ void Terminal::SetScrollPositionChangedCallback(std::function<void(const int, co
_pfnScrollPositionChanged = pfn;
}

// Method Description:
// - Allows setting a callback for when the background color is changed
// Arguments:
// - pfn: a function callback that takes a uint32 (DWORD COLORREF) color in the format 0x00BBGGRR
void Terminal::SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept
{
_pfnBackgroundColorChanged = pfn;
}

// Method Description:
// - Checks if selection is active
// Return Value:
Expand Down
6 changes: 5 additions & 1 deletion src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ class Microsoft::Terminal::Core::Terminal final :
COORD GetCursorPosition() override;
bool EraseCharacters(const unsigned int numChars) override;
bool SetWindowTitle(std::wstring_view title) override;
bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) override;
bool SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
bool SetDefaultForeground(const COLORREF dwColor) override;
bool SetDefaultBackground(const COLORREF dwColor) override;
#pragma endregion

#pragma region ITerminalInput
Expand Down Expand Up @@ -113,6 +115,7 @@ class Microsoft::Terminal::Core::Terminal final :
void SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept;
void SetTitleChangedCallback(std::function<void(const std::wstring_view&)> pfn) noexcept;
void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
void SetBackgroundCallback(std::function<void(const uint32_t)> pfn) noexcept;

void SetCursorVisible(const bool isVisible) noexcept;
bool IsCursorBlinkingAllowed() const noexcept;
Expand All @@ -131,6 +134,7 @@ class Microsoft::Terminal::Core::Terminal final :
std::function<void(std::wstring&)> _pfnWriteInput;
std::function<void(const std::wstring_view&)> _pfnTitleChanged;
std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
std::function<void(const uint32_t)> _pfnBackgroundColorChanged;

std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput;
Expand Down
33 changes: 32 additions & 1 deletion src/cascadia/TerminalCore/TerminalApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ bool Terminal::SetWindowTitle(std::wstring_view title)
// - dwColor: the new COLORREF to use as that color table value.
// Return Value:
// - true iff we successfully updated the color table entry.
bool Terminal::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor)
bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor)
{
if (tableIndex > _colorTable.size())
{
Expand Down Expand Up @@ -219,3 +219,34 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)

return true;
}

// Method Description:
// - Updates the default foreground color from a COLORREF, format 0x00BBGGRR.
// Arguments:
// - dwColor: the new COLORREF to use as the default foreground color
// Return Value:
// - true
bool Terminal::SetDefaultForeground(const COLORREF dwColor)
Jaykul marked this conversation as resolved.
Show resolved Hide resolved
{
_defaultFg = dwColor;

// Repaint everything - the colors might have changed
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}

// Method Description:
// - Updates the default background color from a COLORREF, format 0x00BBGGRR.
// Arguments:
// - dwColor: the new COLORREF to use as the default background color
// Return Value:
// - true
bool Terminal::SetDefaultBackground(const COLORREF dwColor)
{
_defaultBg = dwColor;
_pfnBackgroundColorChanged(dwColor);

// Repaint everything - the colors might have changed
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
24 changes: 23 additions & 1 deletion src/cascadia/TerminalCore/TerminalDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool TerminalDispatch::SetWindowTitle(std::wstring_view title)
// - tableIndex: The VT color table index
// - dwColor: The new RGB color value to use.
// Return Value:
// True if handled successfully. False othewise.
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex,
const DWORD dwColor)
{
Expand All @@ -75,3 +75,25 @@ bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorSty
{
return _terminalApi.SetCursorStyle(cursorStyle);
}

// Method Description:
// - Sets the default foreground color to a new value
// Arguments:
// - dwColor: The new RGB color value to use, in 0x00BBGGRR form
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultForeground(const DWORD dwColor)
{
return _terminalApi.SetDefaultForeground(dwColor);
}

// Method Description:
// - Sets the default background color to a new value
// Arguments:
// - dwColor: The new RGB color value to use, in 0x00BBGGRR form
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultBackground(const DWORD dwColor)
{
return _terminalApi.SetDefaultBackground(dwColor);
}
3 changes: 3 additions & 0 deletions src/cascadia/TerminalCore/TerminalDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc
bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;

bool SetDefaultForeground(const DWORD dwColor) override;
bool SetDefaultBackground(const DWORD dwColor) override;

private:
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;

Expand Down
56 changes: 56 additions & 0 deletions src/host/getset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2170,3 +2170,59 @@ HRESULT DoSrvPrivateSetColorTableEntry(const short index, const COLORREF value)
CATCH_RETURN();

}

// Method Description:
// - Sets the default foreground color to the color specified in value.
// Arguments:
// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR.
// Return Value:
// - S_OK
[[nodiscard]]
HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept
{
try
{
Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation();

gci.SetDefaultForegroundColor(value);

// Update the screen colors if we're not a pty
// No need to force a redraw in pty mode.
if (g.pRender && !gci.IsInVtIoMode())
{
g.pRender->TriggerRedrawAll();
}

return S_OK;
}
CATCH_RETURN();
}

// Method Description:
// - Sets the default background color to the color specified in value.
// Arguments:
// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR.
// Return Value:
// - S_OK
[[nodiscard]]
HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept
{
try
{
Globals& g = ServiceLocator::LocateGlobals();
CONSOLE_INFORMATION& gci = g.getConsoleInformation();

gci.SetDefaultBackgroundColor(value);

// Update the screen colors if we're not a pty
// No need to force a redraw in pty mode.
if (g.pRender && !gci.IsInVtIoMode())
{
g.pRender->TriggerRedrawAll();
}

return S_OK;
}
CATCH_RETURN();
}
6 changes: 6 additions & 0 deletions src/host/getset.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,9 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo);

[[nodiscard]]
HRESULT DoSrvPrivateSetColorTableEntry(const short index, const COLORREF value) noexcept;

[[nodiscard]]
HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept;

[[nodiscard]]
HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept;
24 changes: 24 additions & 0 deletions src/host/outputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,3 +761,27 @@ BOOL ConhostInternalGetSet::PrivateSetColorTableEntry(const short index, const C
{
return SUCCEEDED(DoSrvPrivateSetColorTableEntry(index, value));
}

// Method Description:
// - Connects the PrivateSetDefaultForeground call directly into our Driver Message servicing
// call inside Conhost.exe
// Arguments:
// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR.
// Return Value:
// - TRUE if successful (see DoSrvPrivateSetDefaultForegroundColor). FALSE otherwise.
BOOL ConhostInternalGetSet::PrivateSetDefaultForeground(const COLORREF value) const noexcept
{
return SUCCEEDED(DoSrvPrivateSetDefaultForegroundColor(value));
}

// Method Description:
// - Connects the PrivateSetDefaultBackground call directly into our Driver Message servicing
// call inside Conhost.exe
// Arguments:
// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR.
// Return Value:
// - TRUE if successful (see DoSrvPrivateSetDefaultBackgroundColor). FALSE otherwise.
BOOL ConhostInternalGetSet::PrivateSetDefaultBackground(const COLORREF value) const noexcept
{
return SUCCEEDED(DoSrvPrivateSetDefaultBackgroundColor(value));
}
4 changes: 4 additions & 0 deletions src/host/outputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::

BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override;

BOOL PrivateSetDefaultForeground(const COLORREF value) const noexcept override;

BOOL PrivateSetDefaultBackground(const COLORREF value) const noexcept override;

private:
Microsoft::Console::IIoProvider& _io;
};
Loading