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 switching the scheme based on the app's theme #14064

Merged
25 commits merged into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3d5d88a
inintial buggy fix for syncing OS themes
Sep 23, 2022
5f54750
fixed control preview bug
Oct 3, 2022
43cc9fa
Code cleanup
Oct 3, 2022
e4c2d20
Code cleanup
Oct 3, 2022
b1c5342
updated bug, where custom themes would not update the color scheme
Oct 10, 2022
e4f3625
updated bug, where custom themes would not update the color scheme
Oct 11, 2022
c16b998
PR lhecker comments
Oct 13, 2022
4e40eff
formatting fix
Oct 19, 2022
367d38c
formatting fix
Oct 20, 2022
fdc2c80
Merge remote-tracking branch 'origin/main' into ThemeControlledColorS…
zadjii-msft Nov 14, 2022
8e08d75
I think this is going to be way easier to manage
zadjii-msft Nov 15, 2022
a0e28f1
UI is better. Not good, but better
zadjii-msft Nov 15, 2022
b64b032
hot reloading
zadjii-msft Nov 15, 2022
1b81da9
cleanup some todos
zadjii-msft Nov 15, 2022
d71c56e
schema too folks
zadjii-msft Nov 15, 2022
e70ac18
goodbye LoadSettings, ReloadSettings is my best friend now
zadjii-msft Nov 15, 2022
11460d6
yep. This is just as dumb as it seems
zadjii-msft Nov 16, 2022
b969353
tests man, tests (thread)
zadjii-msft Nov 16, 2022
c823fe6
these weren't me!
zadjii-msft Nov 16, 2022
4e51484
Merge remote-tracking branch 'origin/main' into ThemeControlledColorS…
zadjii-msft Nov 30, 2022
9f251dd
Merge remote-tracking branch 'origin/main' into ThemeControlledColorS…
zadjii-msft Dec 1, 2022
1260705
remove this scheme
zadjii-msft Dec 1, 2022
109ecd9
Merge remote-tracking branch 'origin/main' into ThemeControlledColorS…
zadjii-msft Dec 2, 2022
ef6f660
Merge remote-tracking branch 'origin/main' into ThemeControlledColorS…
zadjii-msft Dec 6, 2022
c56a424
yea I dig it
zadjii-msft Dec 6, 2022
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
17 changes: 17 additions & 0 deletions src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ namespace SettingsModelLocalTests
{
"name": "Different reference",
"colorScheme": "One Half Dark"
},
{
"name": "Different reference / Light and Dark",
"colorScheme":
{
"dark": "One Half Dark",
"light": "One Half Light"
}
}
]
},
Expand Down Expand Up @@ -322,5 +330,14 @@ namespace SettingsModelLocalTests
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().ColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(4) };
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_ARE_EQUAL(L"One Half Light", prof.DefaultAppearance().LightColorSchemeName());
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().ColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
}
}
17 changes: 9 additions & 8 deletions src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,21 +779,22 @@ namespace SettingsModelLocalTests
VERIFY_ARE_EQUAL(6u, settings->ActiveProfiles().Size());
VERIFY_ARE_EQUAL(2u, settings->GlobalSettings().ColorSchemes().Size());

auto createTerminalSettings = [&](const auto& profile, const auto& schemes) {
auto createTerminalSettings = [&](const auto& profile, const auto& schemes, const auto& Theme) {
auto terminalSettings{ winrt::make_self<implementation::TerminalSettings>() };
terminalSettings->_ApplyProfileSettings(profile);
terminalSettings->_ApplyAppearanceSettings(profile.DefaultAppearance(), schemes);
terminalSettings->_ApplyAppearanceSettings(profile.DefaultAppearance(), schemes, Theme);
return terminalSettings;
};

const auto activeProfiles = settings->ActiveProfiles();
const auto colorSchemes = settings->GlobalSettings().ColorSchemes();
const auto terminalSettings0 = createTerminalSettings(activeProfiles.GetAt(0), colorSchemes);
const auto terminalSettings1 = createTerminalSettings(activeProfiles.GetAt(1), colorSchemes);
const auto terminalSettings2 = createTerminalSettings(activeProfiles.GetAt(2), colorSchemes);
const auto terminalSettings3 = createTerminalSettings(activeProfiles.GetAt(3), colorSchemes);
const auto terminalSettings4 = createTerminalSettings(activeProfiles.GetAt(4), colorSchemes);
const auto terminalSettings5 = createTerminalSettings(activeProfiles.GetAt(5), colorSchemes);
const auto currentTheme = settings->GlobalSettings().CurrentTheme();
const auto terminalSettings0 = createTerminalSettings(activeProfiles.GetAt(0), colorSchemes, currentTheme);
const auto terminalSettings1 = createTerminalSettings(activeProfiles.GetAt(1), colorSchemes, currentTheme);
const auto terminalSettings2 = createTerminalSettings(activeProfiles.GetAt(2), colorSchemes, currentTheme);
const auto terminalSettings3 = createTerminalSettings(activeProfiles.GetAt(3), colorSchemes, currentTheme);
const auto terminalSettings4 = createTerminalSettings(activeProfiles.GetAt(4), colorSchemes, currentTheme);
const auto terminalSettings5 = createTerminalSettings(activeProfiles.GetAt(5), colorSchemes, currentTheme);

VERIFY_ARE_EQUAL(til::color(0x12, 0x34, 0x56), terminalSettings0->CursorColor()); // from color scheme
VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1->CursorColor()); // default
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/IControlAppearance.idl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Microsoft.Terminal.Control
// IntenseIsBold and IntenseIsBright are in Core Appearance
Double Opacity { get; };

String ColorSchemeName { get; };
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
// Experimental settings
Boolean RetroTerminalEffect { get; };
String PixelShaderPath { get; };
Expand Down
37 changes: 37 additions & 0 deletions src/cascadia/TerminalSettingsModel/AppearanceConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static constexpr std::string_view SelectionBackgroundKey{ "selectionBackground"
static constexpr std::string_view CursorColorKey{ "cursorColor" };
static constexpr std::string_view LegacyAcrylicTransparencyKey{ "acrylicOpacity" };
static constexpr std::string_view OpacityKey{ "opacity" };
static constexpr std::string_view ColorSchemeKey{ "colorScheme" };
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

AppearanceConfig::AppearanceConfig(winrt::weak_ref<Profile> sourceProfile) :
_sourceProfile(std::move(sourceProfile))
Expand All @@ -32,6 +33,9 @@ winrt::com_ptr<AppearanceConfig> AppearanceConfig::CopyAppearance(const Appearan
appearance->_SelectionBackground = source->_SelectionBackground;
appearance->_CursorColor = source->_CursorColor;
appearance->_Opacity = source->_Opacity;
appearance->_ColorSchemeName = source->_ColorSchemeName;
appearance->_DarkColorSchemeName = source->_DarkColorSchemeName;
appearance->_LightColorSchemeName = source->_LightColorSchemeName;

#define APPEARANCE_SETTINGS_COPY(type, name, jsonKey, ...) \
appearance->_##name = source->_##name;
Expand All @@ -50,6 +54,25 @@ Json::Value AppearanceConfig::ToJson() const
JsonUtils::SetValueForKey(json, SelectionBackgroundKey, _SelectionBackground);
JsonUtils::SetValueForKey(json, CursorColorKey, _CursorColor);
JsonUtils::SetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter<double, IntAsFloatPercentConversionTrait>{});
if (HasDarkColorSchemeName() && HasLightColorSchemeName())
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
{
// check if the setting is coming from the UI, if so grab the ColorSchemeName until the settings UI is fixed.
if (_ColorSchemeName != _DarkColorSchemeName)
bennettnicholas marked this conversation as resolved.
Show resolved Hide resolved
{
JsonUtils::SetValueForKey(json["colorScheme"], "dark", _ColorSchemeName);
JsonUtils::SetValueForKey(json["colorScheme"], "light", _ColorSchemeName);
}
else
{
JsonUtils::SetValueForKey(json["colorScheme"], "dark", _DarkColorSchemeName);
JsonUtils::SetValueForKey(json["colorScheme"], "light", _LightColorSchemeName);
}
}
else if (HasColorSchemeName())
{
JsonUtils::SetValueForKey(json["colorScheme"], "dark", _ColorSchemeName);
JsonUtils::SetValueForKey(json["colorScheme"], "light", _ColorSchemeName);
}
bennettnicholas marked this conversation as resolved.
Show resolved Hide resolved

#define APPEARANCE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
JsonUtils::SetValueForKey(json, jsonKey, _##name);
Expand Down Expand Up @@ -79,6 +102,20 @@ void AppearanceConfig::LayerJson(const Json::Value& json)

JsonUtils::GetValueForKey(json, LegacyAcrylicTransparencyKey, _Opacity);
JsonUtils::GetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter<double, IntAsFloatPercentConversionTrait>{});
if (json["colorScheme"].isString())
{
// to make the UI happy, set ColorSchemeName.
JsonUtils::GetValueForKey(json, ColorSchemeKey, _ColorSchemeName);
_DarkColorSchemeName = _ColorSchemeName;
_LightColorSchemeName = _ColorSchemeName;
}
else if (json["colorScheme"].isObject())
{
// to make the UI happy, set ColorSchemeName to whatever the dark value is.
JsonUtils::GetValueForKey(json["colorScheme"], "dark", _DarkColorSchemeName);
JsonUtils::GetValueForKey(json["colorScheme"], "light", _LightColorSchemeName);
_ColorSchemeName = _DarkColorSchemeName;
}

#define APPEARANCE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
JsonUtils::GetValueForKey(json, jsonKey, _##name);
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalSettingsModel/AppearanceConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, SelectionBackground, nullptr);
INHERITABLE_NULLABLE_SETTING(Model::IAppearanceConfig, Microsoft::Terminal::Core::Color, CursorColor, nullptr);
INHERITABLE_SETTING(Model::IAppearanceConfig, double, Opacity, 1.0);
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, ColorSchemeName, L"Campbell");
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, DarkColorSchemeName, L"Campbell");
INHERITABLE_SETTING(Model::IAppearanceConfig, hstring, LightColorSchemeName, L"Campbell");

#define APPEARANCE_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
INHERITABLE_SETTING(Model::IAppearanceConfig, type, name, ##__VA_ARGS__)
Expand Down
22 changes: 16 additions & 6 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,9 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source)
DUPLICATE_SETTING_MACRO_SUB(appearance, target, SelectionBackground);
DUPLICATE_SETTING_MACRO_SUB(appearance, target, CursorColor);
DUPLICATE_SETTING_MACRO_SUB(appearance, target, Opacity);
DUPLICATE_SETTING_MACRO_SUB(appearance, target, DarkColorSchemeName);
DUPLICATE_SETTING_MACRO_SUB(appearance, target, LightColorSchemeName);
DUPLICATE_SETTING_MACRO_SUB(appearance, target, ColorSchemeName);
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}

// UnfocusedAppearance is treated as a single setting,
Expand Down Expand Up @@ -430,22 +433,29 @@ void CascadiaSettings::_validateSettings()
void CascadiaSettings::_validateAllSchemesExist()
{
const auto colorSchemes = _globals->ColorSchemes();
auto foundInvalidScheme = false;
auto foundInvalidDarkScheme = false;
auto foundInvalidLightScheme = false;
Comment on lines -433 to +436
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't really need two variables here but it's fine haha


for (const auto& profile : _allProfiles)
{
for (const auto& appearance : std::array{ profile.DefaultAppearance(), profile.UnfocusedAppearance() })
{
if (appearance && !colorSchemes.HasKey(appearance.ColorSchemeName()))
if (appearance && !colorSchemes.HasKey(appearance.DarkColorSchemeName()))
{
// Clear the user set color scheme. We'll just fallback instead.
appearance.ClearColorSchemeName();
foundInvalidScheme = true;
// Clear the user set dark color scheme. We'll just fallback instead.
appearance.ClearDarkColorSchemeName();
foundInvalidDarkScheme = true;
}
if (appearance && !colorSchemes.HasKey(appearance.LightColorSchemeName()))
{
// Clear the user set light color scheme. We'll just fallback instead.
appearance.ClearLightColorSchemeName();
foundInvalidLightScheme = true;
}
}
}

if (foundInvalidScheme)
if (foundInvalidDarkScheme || foundInvalidLightScheme)
{
_warnings.Append(SettingsLoadWarnings::UnknownColorScheme);
}
Expand Down
8 changes: 4 additions & 4 deletions src/cascadia/TerminalSettingsModel/IAppearanceConfig.idl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "Profile.idl";
#include "IInheritable.idl.h"

#define INHERITABLE_APPEARANCE_SETTING(Type, Name) \
_BASE_INHERITABLE_SETTING(Type, Name); \
_BASE_INHERITABLE_SETTING(Type, Name); \
Microsoft.Terminal.Settings.Model.IAppearanceConfig Name##OverrideSource { get; }

namespace Microsoft.Terminal.Settings.Model
Expand All @@ -22,9 +22,7 @@ namespace Microsoft.Terminal.Settings.Model
Vertical_Bottom = 0x20
};

[flags]
enum IntenseStyle
{
[flags] enum IntenseStyle {
Bold = 0x1,
Bright = 0x2,
All = 0xffffffff
Expand All @@ -34,6 +32,8 @@ namespace Microsoft.Terminal.Settings.Model
{
Microsoft.Terminal.Settings.Model.Profile SourceProfile { get; };
INHERITABLE_APPEARANCE_SETTING(String, ColorSchemeName);
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
INHERITABLE_APPEARANCE_SETTING(String, DarkColorSchemeName);
INHERITABLE_APPEARANCE_SETTING(String, LightColorSchemeName);
INHERITABLE_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Foreground);
INHERITABLE_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Background);
INHERITABLE_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, SelectionBackground);
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ Author(s):
X(bool, RetroTerminalEffect, "experimental.retroTerminalEffect", false) \
X(hstring, PixelShaderPath, "experimental.pixelShaderPath") \
X(ConvergedAlignment, BackgroundImageAlignment, "backgroundImageAlignment", ConvergedAlignment::Horizontal_Center | ConvergedAlignment::Vertical_Center) \
X(hstring, ColorSchemeName, "colorScheme", L"Campbell") \
X(hstring, BackgroundImagePath, "backgroundImage") \
X(Model::IntenseStyle, IntenseTextStyle, "intenseTextStyle", Model::IntenseStyle::Bright) \
X(Core::AdjustTextMode, AdjustIndistinguishableColors, "adjustIndistinguishableColors", Core::AdjustTextMode::Never)
Expand Down
47 changes: 42 additions & 5 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
const auto globals = appSettings.GlobalSettings();
settings->_ApplyProfileSettings(profile);
settings->_ApplyGlobalSettings(globals);
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes());
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme());

return settings;
}
Expand Down Expand Up @@ -91,7 +91,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
const auto globals = appSettings.GlobalSettings();
auto childImpl = settings->CreateChild();
childImpl->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes());
childImpl->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme());
child = *childImpl;
}

Expand Down Expand Up @@ -183,13 +183,49 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return settingsPair;
}

void TerminalSettings::_ApplyAppearanceSettings(const IAppearanceConfig& appearance, const Windows::Foundation::Collections::IMapView<winrt::hstring, ColorScheme>& schemes)
void TerminalSettings::_ApplyAppearanceSettings(const IAppearanceConfig& appearance,
const Windows::Foundation::Collections::IMapView<winrt::hstring, ColorScheme>& schemes,
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme)
{
_CursorShape = appearance.CursorShape();
_CursorHeight = appearance.CursorHeight();
if (!appearance.ColorSchemeName().empty())

const auto requestedTheme = currentTheme.RequestedTheme();
const auto defaultName = appearance.ColorSchemeName();
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
auto darkName = appearance.DarkColorSchemeName();
auto lightName = appearance.LightColorSchemeName();
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

// If the darkName does not equal the default name, it means the setting change came from the UI or its a bad name. Either will process the same.
if (darkName != defaultName && requestedTheme != winrt::Windows::UI::Xaml::ElementTheme::Default)
{
// if this is a bad name, move on to checking the theme to select the proper default color scheme name.
if (const auto scheme = schemes.TryLookup(defaultName))
{
ApplyColorScheme(scheme);
}
else
{
const auto& schemeName = requestedTheme == winrt::Windows::UI::Xaml::ElementTheme::Dark ? darkName : lightName;
if (const auto scheme = schemes.TryLookup(schemeName))
{
ApplyColorScheme(scheme);
}
}
}
// system theme selected, set the color scheme based off of the system theme.
else if (requestedTheme == winrt::Windows::UI::Xaml::ElementTheme::Default)
{
const auto& schemeName = Windows::UI::Xaml::Application::Current().RequestedTheme() == Windows::UI::Xaml::ApplicationTheme::Dark ? darkName : lightName;
if (const auto scheme = schemes.TryLookup(schemeName))
{
ApplyColorScheme(scheme);
}
}
// application theme selected, set the color scheme based off of the system theme.
else
{
if (const auto scheme = schemes.TryLookup(appearance.ColorSchemeName()))
const auto schemeName = requestedTheme == winrt::Windows::UI::Xaml::ElementTheme::Dark ? darkName : lightName;
if (const auto scheme = schemes.TryLookup(schemeName))
{
ApplyColorScheme(scheme);
}
Expand Down Expand Up @@ -330,6 +366,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
else
{
AppliedColorScheme(scheme);
ColorSchemeName(scheme.Name());
_DefaultForeground = til::color{ scheme.Foreground() };
_DefaultBackground = til::color{ scheme.Background() };
_SelectionBackground = til::color{ scheme.SelectionBackground() };
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalSettingsModel/TerminalSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::TerminalSettings, IFontFeatureMap, FontFeatures);

INHERITABLE_SETTING(Model::TerminalSettings, Model::ColorScheme, AppliedColorScheme);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, ColorSchemeName);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, BackgroundImage);
INHERITABLE_SETTING(Model::TerminalSettings, double, BackgroundImageOpacity, 1.0);

Expand Down Expand Up @@ -170,7 +171,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
void _ApplyAppearanceSettings(const Microsoft::Terminal::Settings::Model::IAppearanceConfig& appearance,
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes);
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes,
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme);

friend class SettingsModelLocalTests::TerminalSettingsTests;
};
Expand Down
Loading