// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #include "pch.h" #include "AppearanceConfig.h" #include "AppearanceConfig.g.cpp" #include "TerminalSettingsSerializationHelpers.h" #include "JsonUtils.h" using namespace winrt::Microsoft::Terminal::Control; using namespace Microsoft::Terminal::Settings::Model; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Microsoft::Terminal::Settings::Model::implementation; static constexpr std::string_view ForegroundKey{ "foreground" }; static constexpr std::string_view BackgroundKey{ "background" }; 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" }; AppearanceConfig::AppearanceConfig(winrt::weak_ref sourceProfile) : _sourceProfile(std::move(sourceProfile)) { } winrt::com_ptr AppearanceConfig::CopyAppearance(const AppearanceConfig* source, winrt::weak_ref sourceProfile) { auto appearance{ winrt::make_self(std::move(sourceProfile)) }; appearance->_Foreground = source->_Foreground; appearance->_Background = source->_Background; appearance->_SelectionBackground = source->_SelectionBackground; appearance->_CursorColor = source->_CursorColor; appearance->_Opacity = source->_Opacity; #define APPEARANCE_SETTINGS_COPY(type, name, jsonKey, ...) \ appearance->_##name = source->_##name; MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_COPY) #undef APPEARANCE_SETTINGS_COPY return appearance; } Json::Value AppearanceConfig::ToJson() const { Json::Value json{ Json::ValueType::objectValue }; JsonUtils::SetValueForKey(json, ForegroundKey, _Foreground); JsonUtils::SetValueForKey(json, BackgroundKey, _Background); JsonUtils::SetValueForKey(json, SelectionBackgroundKey, _SelectionBackground); JsonUtils::SetValueForKey(json, CursorColorKey, _CursorColor); JsonUtils::SetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter{}); #define APPEARANCE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \ JsonUtils::SetValueForKey(json, jsonKey, _##name); MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_TO_JSON) #undef APPEARANCE_SETTINGS_TO_JSON return json; } // Method Description: // - Layer values from the given json object on top of the existing properties // of this object. For any keys we're expecting to be able to parse in the // given object, we'll parse them and replace our settings with values from // the new json object. Properties that _aren't_ in the json object will _not_ // be replaced. // - Optional values that are set to `null` in the json object // will be set to nullopt. // - This is similar to Profile::LayerJson but for AppearanceConfig // Arguments: // - json: an object which should be a partial serialization of an AppearanceConfig object. void AppearanceConfig::LayerJson(const Json::Value& json) { JsonUtils::GetValueForKey(json, ForegroundKey, _Foreground); JsonUtils::GetValueForKey(json, BackgroundKey, _Background); JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _SelectionBackground); JsonUtils::GetValueForKey(json, CursorColorKey, _CursorColor); JsonUtils::GetValueForKey(json, LegacyAcrylicTransparencyKey, _Opacity); JsonUtils::GetValueForKey(json, OpacityKey, _Opacity, JsonUtils::OptionalConverter{}); #define APPEARANCE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \ JsonUtils::GetValueForKey(json, jsonKey, _##name); MTSM_APPEARANCE_SETTINGS(APPEARANCE_SETTINGS_LAYER_JSON) #undef APPEARANCE_SETTINGS_LAYER_JSON } winrt::Microsoft::Terminal::Settings::Model::Profile AppearanceConfig::SourceProfile() { return _sourceProfile.get(); } // Method Description: // - Returns this AppearanceConfig's background image path, if one is set, expanding // any environment variables in the path, if there are any. // - Or if "DesktopWallpaper" is set, then gets the path to the desktops wallpaper. // - This is the same as Profile::ExpandedBackgroundImagePath, but for AppearanceConfig // - NOTE: This is just placeholder for now, eventually the path will no longer be expanded in the settings model // Return Value: // - This profile's expanded background image path / desktops's wallpaper path /the empty string. winrt::hstring AppearanceConfig::ExpandedBackgroundImagePath() { const auto path{ BackgroundImagePath() }; if (path.empty()) { return path; } // checks if the user would like to copy their desktop wallpaper // if so, replaces the path with the desktop wallpaper's path else if (path == L"desktopWallpaper") { WCHAR desktopWallpaper[MAX_PATH]; // "The returned string will not exceed MAX_PATH characters" as of 2020 if (SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, desktopWallpaper, SPIF_UPDATEINIFILE)) { return winrt::hstring{ (desktopWallpaper) }; } else { return winrt::hstring{ L"" }; } } else { return winrt::hstring{ wil::ExpandEnvironmentStringsW(path.c_str()) }; } }