diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 9296cd1eb6c..191f82e0212 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -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", @@ -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.", diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 6ac715084a7..befcbf04561 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -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) { @@ -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() : @@ -5261,57 +5264,71 @@ namespace winrt::TerminalApp::implementation // - requestedTheme: this should be the currently active Theme for the app // Return Value: // - - 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(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()); } 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(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(); + // 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()); } 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(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(); + // 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()); } 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(obj, Colors::Black()); + + _paneResources.broadcastBorderBrush = SolidColorBrush{ actualColor}; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 2705d4453c6..713b527a6c9 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -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); diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index 96cd878b800..f8b863ba277 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -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) \ @@ -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) diff --git a/src/cascadia/TerminalSettingsModel/Theme.cpp b/src/cascadia/TerminalSettingsModel/Theme.cpp index e53c72a79e4..d5afc77f4f6 100644 --- a/src/cascadia/TerminalSettingsModel/Theme.cpp +++ b/src/cascadia/TerminalSettingsModel/Theme.cpp @@ -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; @@ -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 @@ -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: @@ -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(res.Lookup(accentColorKey)) }; - const winrt::WUX::Media::SolidColorBrush accentBrush{ accentColor }; // _getAccentColorForTitlebar should have already filled the alpha // channel in with 255 @@ -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: @@ -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 @@ -250,6 +251,11 @@ winrt::com_ptr Theme::Copy() const { theme->_TabRow = *winrt::get_self(_TabRow)->Copy(); } + if (_Pane) + { + theme->_Pane = *winrt::get_self(_Pane)->Copy(); + } + if (_Tab) { theme->_Tab = *winrt::get_self(_Tab)->Copy(); @@ -334,6 +340,12 @@ void Theme::LogSettingChanges(std::set& 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) diff --git a/src/cascadia/TerminalSettingsModel/Theme.h b/src/cascadia/TerminalSettingsModel/Theme.h index e0892733ae8..73be3b8b8e1 100644 --- a/src/cascadia/TerminalSettingsModel/Theme.h +++ b/src/cascadia/TerminalSettingsModel/Theme.h @@ -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" @@ -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 { diff --git a/src/cascadia/TerminalSettingsModel/Theme.idl b/src/cascadia/TerminalSettingsModel/Theme.idl index cb88aae95a1..f57e983dafc 100644 --- a/src/cascadia/TerminalSettingsModel/Theme.idl +++ b/src/cascadia/TerminalSettingsModel/Theme.idl @@ -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; }; @@ -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; }; @@ -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();