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

Reintroduce the Defaults page and the Reset buttons #10588

Merged
12 commits merged into from
Jul 9, 2021
17 changes: 17 additions & 0 deletions src/cascadia/TerminalSettingsEditor/MainPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static const std::wstring_view launchTag{ L"Launch_Nav" };
static const std::wstring_view interactionTag{ L"Interaction_Nav" };
static const std::wstring_view renderingTag{ L"Rendering_Nav" };
static const std::wstring_view actionsTag{ L"Actions_Nav" };
static const std::wstring_view globalProfileTag{ L"GlobalProfile_Nav" };
static const std::wstring_view addProfileTag{ L"AddProfile" };
static const std::wstring_view colorSchemesTag{ L"ColorSchemes_Nav" };
static const std::wstring_view globalAppearanceTag{ L"GlobalAppearance_Nav" };
Expand Down Expand Up @@ -295,6 +296,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
contentFrame().Navigate(xaml_typename<Editor::Actions>(), winrt::make<ActionsPageNavigationState>(_settingsClone));
}
else if (clickedItemTag == globalProfileTag)
DHowett marked this conversation as resolved.
Show resolved Hide resolved
{
auto profileVM{ _viewModelForProfile(_settingsClone.ProfileDefaults(), _settingsClone) };
profileVM.IsBaseLayer(true);
_lastProfilesNavState = winrt::make<ProfilePageNavigationState>(profileVM,
_settingsClone.GlobalSettings().ColorSchemes(),
_lastProfilesNavState,
*this);

contentFrame().Navigate(xaml_typename<Editor::Profiles>(), _lastProfilesNavState);
}
else if (clickedItemTag == colorSchemesTag)
{
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), _colorSchemesNavState);
Expand Down Expand Up @@ -456,4 +468,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
SettingsNav().SelectedItem(newSelectedItem);
_Navigate(newSelectedItem.try_as<MUX::Controls::NavigationViewItem>().Tag().try_as<Editor::ProfileViewModel>());
}

bool MainPage::ShowBaseLayerMenuItem() const noexcept
{
return Feature_ShowProfileDefaultsInSettings::IsEnabled();
}
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsEditor/MainPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
bool TryPropagateHostingWindow(IInspectable object) noexcept;
uint64_t GetHostingWindow() const noexcept;

bool ShowBaseLayerMenuItem() const noexcept;

TYPED_EVENT(OpenJson, Windows::Foundation::IInspectable, Model::SettingsTarget);

private:
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsEditor/MainPage.idl
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ namespace Microsoft.Terminal.Settings.Editor
// Due to the aforementioned bug, we can't use IInitializeWithWindow _here_ either.
// Let's just smuggle the HWND in as a UInt64 :|
void SetHostingWindow(UInt64 window);

Boolean ShowBaseLayerMenuItem { get; };
}
}
9 changes: 9 additions & 0 deletions src/cascadia/TerminalSettingsEditor/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@

<muxc:NavigationViewItemHeader x:Uid="Nav_Profiles" />

<muxc:NavigationViewItem x:Name="BaseLayerMenuItem"
x:Uid="Nav_ProfileDefaults"
Tag="GlobalProfile_Nav"
Visibility="{x:Bind ShowBaseLayerMenuItem}">
DHowett marked this conversation as resolved.
Show resolved Hide resolved
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE81E;" />
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>

</muxc:NavigationView.MenuItems>

<muxc:NavigationView.PaneFooter>
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalSettingsEditor/Profiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

Model::TerminalSettings ProfileViewModel::TermSettings() const
{
return Model::TerminalSettings::CreateWithProfileByID(_appSettings, _profile.Guid(), nullptr).DefaultSettings();
return Model::TerminalSettings::CreateWithProfile(_appSettings, _profile, nullptr).DefaultSettings();
}

// Method Description:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,8 @@
<comment>Header for a menu item. This opens the JSON file that is used to log the app's settings.</comment>
</data>
<data name="Nav_ProfileDefaults.Content" xml:space="preserve">
<value>Base layer</value>
<comment>Header for the "base layer" menu item. This navigates to a page that lets you see and modify settings that affect profiles. The base layer is the lowest layer of profile settings that all other profile settings are based on. If a profile doesn't define a setting, base layer is responsible for figuring out what that setting is supposed to be.</comment>
<value>Defaults</value>
<comment>Header for the "defaults" menu item. This navigates to a page that lets you see and modify settings that affect profiles. This is the lowest layer of profile settings that all other profile settings are based on. If a profile doesn't define a setting, this page is responsible for figuring out what that setting is supposed to be.</comment>
</data>
<data name="Nav_Rendering.Content" xml:space="preserve">
<value>Rendering</value>
Expand Down Expand Up @@ -1012,7 +1012,7 @@
</data>
<data name="Profile_BaseLayerDisclaimer.Text" xml:space="preserve">
<value>Settings defined here will apply to all profiles unless they are overridden by a profile's settings.</value>
<comment>A disclaimer presented at the top of a page. See "Nav_ProfileDefaults.Content" for a description on what the base layer does in the app.</comment>
<comment>A disclaimer presented at the top of a page. See "Nav_ProfileDefaults.Content" for a description on what the defaults layer does in the app.</comment>
</data>
<data name="Profile_DeleteConfirmationButton.Content" xml:space="preserve">
<value>Yes, delete profile</value>
Expand Down Expand Up @@ -1087,8 +1087,8 @@
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
</data>
<data name="SettingContainer_OverrideMessageBaseLayer" xml:space="preserve">
<value>Reset to base layer value.</value>
<comment>"base layer" should match Nav_ProfileDefaults.Content's text. This is a text label on a button.</comment>
<value>Reset to inherited value.</value>
<comment>This button will remove a user's customization from a given setting, restoring it to the value that the profile inherited. This is a text label on a button.</comment>
</data>
<data name="ColorScheme_TerminalColorsHeader.Text" xml:space="preserve">
<value>Terminal colors</value>
Expand Down
64 changes: 32 additions & 32 deletions src/cascadia/TerminalSettingsEditor/SettingContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_SettingOverrideSourceProperty =
DependencyProperty::Register(
L"SettingOverrideSource",
xaml_typename<bool>(),
xaml_typename<IInspectable>(),
DHowett marked this conversation as resolved.
Show resolved Hide resolved
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ nullptr });
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingContainer::_OnHasSettingValueChanged } });
}
}

Expand Down Expand Up @@ -152,17 +152,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// We want to be smart about showing the override system.
// Don't just show it if the user explicitly set the setting.
// If the tooltip is empty, we'll hide the entire override system.
hstring tooltip{};

const auto& settingSrc{ SettingOverrideSource() };
if (const auto& profile{ settingSrc.try_as<Model::Profile>() })
{
tooltip = _GenerateOverrideMessage(profile);
}
else if (const auto& appearanceConfig{ settingSrc.try_as<Model::AppearanceConfig>() })
{
tooltip = _GenerateOverrideMessage(appearanceConfig.SourceProfile());
}
const auto tooltip{ _GenerateOverrideMessage(settingSrc) };

Controls::ToolTipService::SetToolTip(button, box_value(tooltip));
button.Visibility(tooltip.empty() ? Visibility::Collapsed : Visibility::Visible);
Expand All @@ -182,35 +174,43 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// - profile: the profile that defines the setting (aka SettingOverrideSource)
// Return Value:
// - text specifying where the setting was defined. If empty, we don't want to show the system.
hstring SettingContainer::_GenerateOverrideMessage(const Model::Profile& profile)
hstring SettingContainer::_GenerateOverrideMessage(const IInspectable& settingOrigin)
{
const auto originTag{ profile.Origin() };
if (originTag == Model::OriginTag::InBox)
// We only get here if the user had an override in place.
Model::OriginTag originTag{ Model::OriginTag::None };
winrt::hstring source;

if (const auto& profile{ settingOrigin.try_as<Model::Profile>() })
{
// in-box profile
return {};
source = profile.Source();
originTag = profile.Origin();
}
else if (originTag == Model::OriginTag::Generated)
else if (const auto& appearanceConfig{ settingOrigin.try_as<Model::AppearanceConfig>() })
{
// from a dynamic profile generator
return {};
const auto profile = appearanceConfig.SourceProfile();
source = profile.Source();
originTag = profile.Origin();
}
else if (originTag == Model::OriginTag::Fragment)

if constexpr (Feature_ShowProfileDefaultsInSettings::IsEnabled())
{
// from a fragment extension
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, profile.Source()) };
// EXPERIMENTAL FEATURE
// We will display arrows for all origins, and informative tooltips for Fragments and Generated
if (originTag == Model::OriginTag::Fragment || originTag == Model::OriginTag::Generated)
{
// from a fragment extension or generated profile
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, source) };
}
return RS_(L"SettingContainer_OverrideMessageBaseLayer");
}
else

// STABLE FEATURE
// We will only display arrows and informative tooltips for Fragments
if (originTag == Model::OriginTag::Fragment)
{
// base layer
// TODO GH#3818: When we add profile inheritance as a setting,
// we'll need an extra conditional check to see if this
// is the base layer or some other profile

// GH#9539: Base Layer has been removed from the Settings UI.
// In the event that the Base Layer comes back,
// return RS_(L"SettingContainer_OverrideMessageBaseLayer") instead
return {};
// from a fragment extension
return hstring{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideMessageFragmentExtension") }, source) };
}
return {}; // no tooltip
}
}
2 changes: 1 addition & 1 deletion src/cascadia/TerminalSettingsEditor/SettingContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
private:
static void _InitializeProperties();
static void _OnHasSettingValueChanged(Windows::UI::Xaml::DependencyObject const& d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const& e);
static hstring _GenerateOverrideMessage(const Model::Profile& profile);
static hstring _GenerateOverrideMessage(const IInspectable& settingOrigin);
void _UpdateOverrideSystem();
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ void CascadiaSettings::LayerJson(const Json::Value& json)
void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
{
// Layer the json on top of an existing profile, if we have one:
winrt::com_ptr<implementation::Profile> profile{ nullptr };
auto profileIndex{ _FindMatchingProfileIndex(profileJson) };
if (profileIndex)
{
Expand All @@ -862,6 +863,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
// When we loaded Profile.Defaults, we created an empty child already.
// So this just populates the empty child
parent->LayerJson(profileJson);
profile.copy_from(parent);
}
else
{
Expand All @@ -871,6 +873,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)

// replace parent in _profiles with child
_allProfiles.SetAt(*profileIndex, *childImpl);
profile = std::move(childImpl);
}
}
else
Expand All @@ -880,7 +883,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
// `source`. Dynamic profiles _must_ be layered on an existing profile.
if (!Profile::IsDynamicProfileObject(profileJson))
{
auto profile{ winrt::make_self<Profile>() };
profile = winrt::make_self<Profile>();

// GH#2325: If we have a set of default profile settings, set that as my parent.
// We _won't_ have these settings yet for defaults, dynamic profiles.
Expand All @@ -893,6 +896,12 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson)
_allProfiles.Append(*profile);
}
}

if (profile && _userDefaultProfileSettings)
{
// If we've loaded defaults{} we're in the "user settings" phase for sure
profile->Origin(OriginTag::User);
}
}

// Method Description:
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalSettingsModel/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

void _FinalizeInheritance() override;

WINRT_PROPERTY(OriginTag, Origin, OriginTag::Custom);
WINRT_PROPERTY(OriginTag, Origin, OriginTag::None);

INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
INHERITABLE_SETTING(Model::Profile, hstring, Name, L"Default");
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/Profile.idl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace Microsoft.Terminal.Settings.Model
// This tag is used to identify the context in which the Profile was created
enum OriginTag
{
Custom = 0,
None = 0,
User,
InBox,
Generated,
Fragment,
Expand Down
24 changes: 20 additions & 4 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Return Value:
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
// one for when the terminal is focused and the other for when the terminal is unfocused
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfileByID(const Model::CascadiaSettings& appSettings, winrt::guid profileGuid, const IKeyBindings& keybindings)
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const IKeyBindings& keybindings)
{
auto settings{ winrt::make_self<TerminalSettings>() };
settings->_KeyBindings = keybindings;

const auto profile = appSettings.FindProfile(profileGuid);
THROW_HR_IF_NULL(E_INVALIDARG, profile);

const auto globals = appSettings.GlobalSettings();
settings->_ApplyProfileSettings(profile);
settings->_ApplyGlobalSettings(globals);
Expand All @@ -86,6 +83,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return winrt::make<TerminalSettingsCreateResult>(*settings, child);
}

// Method Description:
// - Create a TerminalSettingsCreateResult for the provided profile guid. We'll
// use the guid to look up the profile that should be used to
// create these TerminalSettings. Then, we'll apply settings contained in the
// global and profile settings to the instance.
// Arguments:
// - appSettings: the set of settings being used to construct the new terminal
// - profileGuid: the unique identifier (guid) of the profile
// - keybindings: the keybinding handler
// Return Value:
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
// one for when the terminal is focused and the other for when the terminal is unfocused
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfileByID(const Model::CascadiaSettings& appSettings, winrt::guid profileGuid, const IKeyBindings& keybindings)
{
const auto profile = appSettings.FindProfile(profileGuid);
THROW_HR_IF_NULL(E_INVALIDARG, profile);
return CreateWithProfile(appSettings, profile, keybindings);
}

// Method Description:
// - Create a TerminalSettings object for the provided newTerminalArgs. We'll
// use the newTerminalArgs to look up the profile that should be used to
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
TerminalSettings() = default;

static Model::TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
const Model::Profile& profile,
const Control::IKeyBindings& keybindings);

static Model::TerminalSettingsCreateResult CreateWithProfileByID(const Model::CascadiaSettings& appSettings,
guid profileGuid,
const Control::IKeyBindings& keybindings);
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Microsoft.Terminal.Settings.Model
{
TerminalSettings();

static TerminalSettingsCreateResult CreateWithProfile(CascadiaSettings appSettings, Profile profile, Microsoft.Terminal.Control.IKeyBindings keybindings);
static TerminalSettingsCreateResult CreateWithProfileByID(CascadiaSettings appSettings, Guid profileGuid, Microsoft.Terminal.Control.IKeyBindings keybindings);
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(CascadiaSettings appSettings, NewTerminalArgs newTerminalArgs, Microsoft.Terminal.Control.IKeyBindings keybindings);
static TerminalSettingsCreateResult CreateWithParent(TerminalSettingsCreateResult parent);
Expand Down
9 changes: 9 additions & 0 deletions src/features.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,13 @@
<brandingToken>WindowsInbox</brandingToken>
</alwaysEnabledBrandingTokens>
</feature>

<feature>
<name>Feature_ShowProfileDefaultsInSettings</name>
<description>Whether to show the "defaults" page in the Terminal settings UI</description>
<id>10430</id>
<stage>AlwaysEnabled</stage>
<!-- This feature will not ship to Stable until it is complete. -->
Copy link
Member

Choose a reason for hiding this comment

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

Project management question:
Do we (want to) have an issue tracking this? Technically it'd be #10430, but I know we hope to iterate on this before going to stable. Idk if you want to keep some kind of issue open to track "get this in a position we're ready for it to go into stable"?

Copy link
Member Author

Choose a reason for hiding this comment

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

I feel like we're not gonna forget about this one no matter how we do it

Copy link
Member Author

Choose a reason for hiding this comment

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

i added 10430 to the <id> field in the feature doc

<alwaysDisabledReleaseTokens />
</feature>
</featureStaging>