Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2020,6 +2020,24 @@
}
}
},
"PaneTheme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the panes",
"properties": {
"activeBorderColor": {
"description": "The color of the pane border when the pane is active",
"$ref": "#/$defs/ThemeColor"
},
"inactiveBorderColor": {
"description": "The color of the pane border when the pane is Inactive",
"$ref": "#/$defs/ThemeColor"
},
"borderColor": {
"description": "The color of the pane border ",
"$ref": "#/$defs/ThemeColor"
}
}
},
"TabRowTheme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the tab row",
Expand Down Expand Up @@ -2061,17 +2079,19 @@
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
"$ref": "#/$defs/ThemeColor"
},
"unfocusedFrame": {
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
"$ref": "#/$defs/ThemeColor"
},
"showWorkspacesButton": {
"description": "When set to true, the workspaces button will be shown in the tab row.",
"type": "boolean",
"default": true
"pane": {
"$ref": "#/$defs/PaneTheme",
"unfocusedFrame": {
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
"$ref": "#/$defs/ThemeColor"
},
"showWorkspacesButton": {
"description": "When set to true, the workspaces button will be shown in the tab row.",
"type": "boolean",
"default": true
}
}
}
},
},
"Theme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the window. This controls things like the titlebar, the tabs, the application theme.",
Expand Down
105 changes: 61 additions & 44 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5139,8 +5139,21 @@ namespace winrt::TerminalApp::implementation
const auto theme = _settings.GlobalSettings().CurrentTheme();
auto requestedTheme{ theme.RequestedTheme() };

Media::Brush terminalBrush{ nullptr };
if (const auto tab{ _GetFocusedTabImpl() })
{
if (const auto& pane{ tab->GetActivePane() })
{
if (const auto& lastContent{ pane->GetLastFocusedContent() })
{
terminalBrush = lastContent.BackgroundBrush(); // the default value that we want on evaluate
}
}
}


{
_updatePaneResources(requestedTheme);
_updatePaneResources(requestedTheme, terminalBrush);

for (const auto& tab : _tabs)
{
Expand All @@ -5163,17 +5176,7 @@ namespace winrt::TerminalApp::implementation

til::color bgColor = backgroundSolidBrush.Color();

Media::Brush terminalBrush{ nullptr };
if (const auto tab{ _GetFocusedTabImpl() })
{
if (const auto& pane{ tab->GetActivePane() })
{
if (const auto& lastContent{ pane->GetLastFocusedContent() })
{
terminalBrush = lastContent.BackgroundBrush();
}
}
}


// GH#19604: Get the theme's tabRow color to use as the acrylic tint.
const auto tabRowBg{ theme.TabRow() ? (_activated ? theme.TabRow().Background() :
Expand Down Expand Up @@ -5261,57 +5264,71 @@ namespace winrt::TerminalApp::implementation
// - requestedTheme: this should be the currently active Theme for the app
// Return Value:
// - <none>
void TerminalPage::_updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme)
void TerminalPage::_updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme, const Media::Brush& terminalBrush)
{
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto res = Application::Current().Resources();
const auto accentColorKey = winrt::box_value(L"SystemAccentColor");
if (res.HasKey(accentColorKey))
const auto unfocusedBorderBrushKey = winrt::box_value(L"UnfocusedBorderBrush");
const auto broadcastColorKey = winrt::box_value(L"BroadcastPaneBorderColor");


const auto paneActive = theme.Pane() ? theme.Pane().ActiveBorderColor() : nullptr;
const auto paneInactive = theme.Pane() ? theme.Pane().InactiveBorderColor() : nullptr;
const auto paneBroadcast = theme.Pane() ? theme.Pane().BorderColor() : nullptr;
if (paneActive)
{
const auto colorFromResources = ThemeLookup(res, requestedTheme, accentColorKey);
// If SystemAccentColor is _not_ a Color for some reason, use
// Transparent as the color, so we don't do this process again on
// the next pane (by leaving s_focusedBorderBrush nullptr)
auto actualColor = winrt::unbox_value_or<Color>(colorFromResources, Colors::Black());
_paneResources.focusedBorderBrush = SolidColorBrush(actualColor);
// using evaluate to make sure that we either get
// the value that we want and incase the value is
// somehow null(should be impossible) switch's to
// default brush

_paneResources.focusedBorderBrush = SolidColorBrush((paneActive.Evaluate(res, terminalBrush, false)).try_as<Media::SolidColorBrush>());
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
_paneResources.focusedBorderBrush = SolidColorBrush{ Colors::Black() };
// MAKE SURE TO USE ThemeLookup, so that we get the correct resource for
// the requestedTheme, not just the value from the resources
const auto colorFromResources = ThemeLookup(res, requestedTheme, accentColorKey);
auto actualColor = winrt::unbox_value_or<Color>(colorFromResources, Colors::Black());

_paneResources.focusedBorderBrush = SolidColorBrush{actualColor};
}

const auto unfocusedBorderBrushKey = winrt::box_value(L"UnfocusedBorderBrush");
if (res.HasKey(unfocusedBorderBrushKey))
if (paneInactive)
{
// MAKE SURE TO USE ThemeLookup, so that we get the correct resource for
// the requestedTheme, not just the value from the resources (which
// might not respect the settings' requested theme)
auto obj = ThemeLookup(res, requestedTheme, unfocusedBorderBrushKey);
_paneResources.unfocusedBorderBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
// using evaluate to make sure that we either get
// the value that we want and incase the value is
// somehow null(should be impossible) switch's to
// default brush
_paneResources.unfocusedBorderBrush = SolidColorBrush((paneInactive.Evaluate(res, terminalBrush, false)).try_as<Media::SolidColorBrush>());
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
_paneResources.unfocusedBorderBrush = SolidColorBrush{ Colors::Black() };
// MAKE SURE TO USE ThemeLookup, so that we get the correct resource for
// the requestedTheme, not just the value from the resources
auto obj = ThemeLookup(res, requestedTheme, unfocusedBorderBrushKey);
auto actualColor = winrt::unbox_value_or<Color>(obj, Colors::Blue());

_paneResources.unfocusedBorderBrush = SolidColorBrush{ actualColor};
}

const auto broadcastColorKey = winrt::box_value(L"BroadcastPaneBorderColor");
if (res.HasKey(broadcastColorKey))
if (paneBroadcast)
{
// MAKE SURE TO USE ThemeLookup
auto obj = ThemeLookup(res, requestedTheme, broadcastColorKey);
_paneResources.broadcastBorderBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
// using evaluate to make sure that we either get
// the value that we want and incase the value is
// somehow null(should be impossible) switch's to
// default brush
_paneResources.broadcastBorderBrush = SolidColorBrush((paneBroadcast.Evaluate(res, terminalBrush, false)).try_as<Media::SolidColorBrush>());
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
_paneResources.broadcastBorderBrush = SolidColorBrush{ Colors::Black() };
// MAKE SURE TO USE ThemeLookup, so that we get the correct resource for
// the requestedTheme, not just the value from the resources
auto obj = ThemeLookup(res, requestedTheme, broadcastColorKey);
auto actualColor = winrt::unbox_value_or<Color>(obj, Colors::Black());

_paneResources.broadcastBorderBrush = SolidColorBrush{ actualColor};
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ namespace winrt::TerminalApp::implementation

void _updateThemeColors();
void _updateAllTabCloseButtons();
void _updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
void _updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme, const winrt::Windows::UI::Xaml::Media::Brush& terminalBrush);

safe_void_coroutine _ControlCompletionsChangedHandler(const winrt::Windows::Foundation::IInspectable sender, const winrt::Microsoft::Terminal::Control::CompletionsChangedEventArgs args);

Expand Down
9 changes: 8 additions & 1 deletion src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ Author(s):
X(winrt::Microsoft::Terminal::Settings::Model::WindowTheme, Window, "window", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::SettingsTheme, Settings, "settings", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::TabRowTheme, TabRow, "tabRow", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::TabTheme, Tab, "tab", nullptr)
X(winrt::Microsoft::Terminal::Settings::Model::TabTheme, Tab, "tab", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::PaneTheme, Pane, "pane", nullptr)


#define MTSM_THEME_WINDOW_SETTINGS(X) \
X(winrt::Windows::UI::Xaml::ElementTheme, RequestedTheme, "applicationTheme", winrt::Windows::UI::Xaml::ElementTheme::Default) \
Expand All @@ -177,3 +179,8 @@ Author(s):
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, UnfocusedBackground, "unfocusedBackground", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::IconStyle, IconStyle, "iconStyle", winrt::Microsoft::Terminal::Settings::Model::IconStyle::Default) \
X(winrt::Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility, ShowCloseButton, "showCloseButton", winrt::Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility::Always)

#define MTSM_THEME_PANE_SETTINGS(X) \
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, ActiveBorderColor, "activeBorderColor", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, InactiveBorderColor, "inactiveBorderColor", nullptr) \
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, BorderColor, "borderColor", nullptr)
20 changes: 16 additions & 4 deletions src/cascadia/TerminalSettingsModel/Theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "TabTheme.g.cpp"
#include "ThemePair.g.cpp"
#include "Theme.g.cpp"
#include "PaneTheme.g.cpp"

using namespace ::Microsoft::Console;
using namespace Microsoft::Terminal::Settings::Model;
Expand Down Expand Up @@ -60,6 +61,7 @@ THEME_OBJECT(WindowTheme, MTSM_THEME_WINDOW_SETTINGS);
THEME_OBJECT(SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
THEME_OBJECT(TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
THEME_OBJECT(TabTheme, MTSM_THEME_TAB_SETTINGS);
THEME_OBJECT(PaneTheme, MTSM_THEME_PANE_SETTINGS);

#undef THEME_SETTINGS_COPY
#undef THEME_SETTINGS_TO_JSON
Expand Down Expand Up @@ -129,7 +131,6 @@ winrt::WUX::Media::Brush ThemeColor::Evaluate(const winrt::WUX::ResourceDictiona
const bool forTitlebar)
{
static const auto accentColorKey{ winrt::box_value(L"SystemAccentColor") };

switch (ColorType())
{
case ThemeColorType::Accent:
Expand All @@ -139,9 +140,8 @@ winrt::WUX::Media::Brush ThemeColor::Evaluate(const winrt::WUX::ResourceDictiona
// much of this logic is rapidly changing. We're not gonna mess with
// that, since it seems there's no good way to reverse engineer that.
til::color accentColor = forTitlebar ?
_getAccentColorForTitlebar() :
_getAccentColorForTitlebar() :
til::color{ winrt::unbox_value<winrt::Windows::UI::Color>(res.Lookup(accentColorKey)) };

const winrt::WUX::Media::SolidColorBrush accentBrush{ accentColor };
// _getAccentColorForTitlebar should have already filled the alpha
// channel in with 255
Expand Down Expand Up @@ -172,7 +172,7 @@ winrt::WUX::Media::Brush ThemeColor::Evaluate(const winrt::WUX::ResourceDictiona
// tab.unfocusedBackground property.
uint8_t ThemeColor::UnfocusedTabOpacity() const noexcept
{
switch (ColorType())
switch (ColorType())
{
case ThemeColorType::Accent:
case ThemeColorType::TerminalBackground:
Expand Down Expand Up @@ -224,6 +224,7 @@ THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, WindowTheme,
THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, TabTheme, MTSM_THEME_TAB_SETTINGS);
THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, PaneTheme, MTSM_THEME_PANE_SETTINGS);

#undef THEME_SETTINGS_FROM_JSON
#undef THEME_SETTINGS_TO_JSON
Expand All @@ -250,6 +251,11 @@ winrt::com_ptr<Theme> Theme::Copy() const
{
theme->_TabRow = *winrt::get_self<implementation::TabRowTheme>(_TabRow)->Copy();
}
if (_Pane)
{
theme->_Pane = *winrt::get_self<implementation::PaneTheme>(_Pane)->Copy();
}

if (_Tab)
{
theme->_Tab = *winrt::get_self<implementation::TabTheme>(_Tab)->Copy();
Expand Down Expand Up @@ -334,6 +340,12 @@ void Theme::LogSettingChanges(std::set<std::string>& changes, const std::string_
const auto outerJsonKey = outerTabJsonKey;
MTSM_THEME_TAB_SETTINGS(LOG_IF_SET)
}

if(isPaneSet){
const auto obj = _Pane;
const auto outerJsonKey = outerTabJsonKey;
MTSM_THEME_PANE_SETTINGS(LOG_IF_SET)
}
#undef LOG_IF_SET
#undef GENERATE_SET_CHECK_AND_JSON_KEYS
#pragma warning(pop)
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/Theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Author(s):
#include "TabTheme.g.h"
#include "ThemePair.g.h"
#include "Theme.g.h"
#include "PaneTheme.g.h"

#include "JsonUtils.h"

Expand Down Expand Up @@ -85,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
THEME_OBJECT(SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
THEME_OBJECT(TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
THEME_OBJECT(TabTheme, MTSM_THEME_TAB_SETTINGS);
THEME_OBJECT(PaneTheme, MTSM_THEME_PANE_SETTINGS);

struct Theme : ThemeT<Theme>
{
Expand Down
15 changes: 13 additions & 2 deletions src/cascadia/TerminalSettingsModel/Theme.idl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ namespace Microsoft.Terminal.Settings.Model
Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
}

runtimeclass WindowTheme {
runtimeclass WindowTheme
{
Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
Boolean UseMica { get; };
Boolean RainbowFrame { get; };
Expand All @@ -67,10 +68,17 @@ namespace Microsoft.Terminal.Settings.Model
ThemeColor UnfocusedFrame { get; };
}

runtimeclass TabRowTheme {
runtimeclass TabRowTheme
{
ThemeColor Background { get; };
ThemeColor UnfocusedBackground { get; };
}
runtimeclass PaneTheme
{
ThemeColor BorderColor{ get; };
ThemeColor InactiveBorderColor { get; };
ThemeColor ActiveBorderColor { get; };
}

runtimeclass TabTheme {
ThemeColor Background { get; };
Expand All @@ -97,6 +105,9 @@ namespace Microsoft.Terminal.Settings.Model
// tab.* Namespace
TabTheme Tab { get; };

// pane.* Namespace
PaneTheme Pane { get; };

// A helper for retrieving the RequestedTheme out of the window property
Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
static Boolean IsSystemInDarkTheme();
Expand Down
Loading