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

Introduce setting override tracking and update SettingContainer #9079

Merged
22 commits merged into from Feb 19, 2021

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Feb 9, 2021

This PR adds improved override message generation for inheritance in
SUI. The settings model now has an OriginTag to be able to denote
where a Profile came from. This tag is used in the SettingContainer
to generate a more specific override message.

References

#6800 - SUI Epic
#8919 - SUI Inheritance PR
#8804 - SUI Inheritance (old issue)

Detailed Description of the Pull Request / Additional comments

  • Terminal Settings Model
    • Introduced PROJECTED_SETTING as a macro to more easily declare the
      functions for each setting
    • Introduced <setting>OverrideSource which finds the Profile that
      has <setting> defined
    • Introduced OriginTag Profile::Origin {Custom, InBox, Generated} to
      trace where a profile came from
    • DefaultProfileUtils creates profiles for profile generators. So
      that now sets the Origin tag to Generated
    • CascadiaSettings::LoadDefaults() tags all profiles created as
      InBox.
    • The view model had to ingest the API change to be able to interact
      with <setting>OverrideSource
  • Override Message Generation
    • The reset button now has a more specific tooltip
    • The reset button now only appears if base layer is being overridden
    • We use the settings model changes to determine the message to
      display for the target

Validation Steps Performed

Tested the following cases:

  • overrides nothing (inherited setting)
  • overrides value inherited from...
    • base layer
    • a profile generator
    • in-box profile
  • global settings should not have this feature

@carlos-zamora carlos-zamora added Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Area-Settings UI Anything specific to the SUI labels Feb 9, 2021
Copy link
Member Author

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

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

I'm chatting with @cinnamon-msft after lunch to do a bit of wordsmithing.

Comment on lines 258 to 261
// '{}' was not found
// fallback to more ambiguous version
hstring overrideMsg{ fmt::format(std::wstring_view{ RS_(L"SettingContainer_OverrideIntro") }, RS_(L"SettingContainer_OverrideTarget")) };
tb.Text(overrideMsg);
Copy link
Member Author

Choose a reason for hiding this comment

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

This should only happen if the localization was messed up. Idk if there's a way to get around this? Or handle it better?

Comment on lines 314 to 317
// Hook up the hyperlinks from SettingContainer
_RegisterNavigationHandlers(GeneralStack());
_RegisterNavigationHandlers(AppearanceStack());
_RegisterNavigationHandlers(AdvancedStack());
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'm not happy about this one. But we could leverage this to access the setting containers via code now.

}
else
{
// TODO #1690: add special handling for proto-extensions here
Copy link
Member Author

Choose a reason for hiding this comment

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

Chatted with @PankajBhojwani about proto-extensions. This should mostly just work. Only changes that would be needed for proto-extensions are...

  • tag profiles from proto-extensions
  • use Profile::Source to create msgTarget
  • add a hyperlink for a read-only view of the proto-extension

@carlos-zamora carlos-zamora marked this pull request as ready for review February 9, 2021 20:26
@carlos-zamora
Copy link
Member Author

Some more annoying news. It looks like the screen reader doesn't read the hyperlink. I've tried explicitly setting the automation properties as well and no luck.

Hyperlinks seem accessible in XAML Controls gallery. I'm worried this may be a XAML Islands issue? I'm looking more into that now.

@zadjii-msft
Copy link
Member

Hyperlinks seem accessible in XAML Controls gallery. I'm worried this may be a XAML Islands issue? I'm looking more into that now.

Check the About dialog

@carlos-zamora
Copy link
Member Author

Hyperlinks seem accessible in XAML Controls gallery. I'm worried this may be a XAML Islands issue? I'm looking more into that now.

Check the About dialog

The links in there are HyperlinkButtons. They work just fine. I'm guessing they rely on the a11y stuff for buttons so that's why?

@DHowett
Copy link
Member

DHowett commented Feb 9, 2021

I don't expect that this is an islands-specific issue.

@carlos-zamora
Copy link
Member Author

Now that the text block is removed, we don't have the accessibility issue.

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

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

I suppose these are all nits? But there's enough of them that I'm just gonna leave a comment for now.

@carlos-zamora carlos-zamora changed the title Add hyperlinks to Settings UI inheritance mechanism Introduce setting override tracking and update SettingContainer Feb 17, 2021
<value>a lower layer</value>
<comment>This is the object of "SettingContainer_OverrideIntro".</comment>
<data name="SettingContainer_OverrideMessageBaseLayer" xml:space="preserve">
<value>Reset to base layer value</value>
Copy link
Member

Choose a reason for hiding this comment

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

if we're only gonna do base layer, should we still add all of the source tracking? It seems our new needs are satisfied by the existence of Has/Clear in the model.

Copy link
Member Author

Choose a reason for hiding this comment

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

We still need source tracking for a few reasons:

  1. need to specifically detect when we're overriding "base layer" as opposed to "in-box" or "generated" profile object
  2. we'll probably use some of this for telemetry
  3. in preparation for profile inheritance, we'll still need to distinguish a profile that exists from one that isn't exposed to the user

@carlos-zamora carlos-zamora force-pushed the dev/cazamor/sui/inheritance-hyperlinks branch from 526eb92 to 500c38e Compare February 17, 2021 19:21
@@ -5,6 +5,7 @@
#include "SettingContainer.h"
#include "SettingContainer.g.cpp"
#include "LibraryResources.h"
#include "../TerminalSettingsModel/LegacyProfileGeneratorNamespaces.h"
Copy link
Member

Choose a reason for hiding this comment

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

is this required? Rather not include things directly out of TSM

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, this was a relic of when we were detecting the specific profile generator. Removed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Had to add this back in to be able to detect when we're overriding a setting from the proto-extension vs one of our profile generators

// no source; we're using the system-default value
tooltip = L"";
}
else if (const auto& profile{ settingSrc.try_as<Model::Profile>() })
Copy link
Member

Choose a reason for hiding this comment

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

i </3 that SettingContainer knows what a profile is

Copy link
Member

Choose a reason for hiding this comment

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

I concur - almost seems like we should have ProfileSettingContainer : SettingContainer that allows for reverting to the parent, but only for settings in profiles.

All this is terrible, but let's not pretend our settings model was designed for a GUI.

Copy link
Member Author

Choose a reason for hiding this comment

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

Long-term, we should probably move more of this responsibility over the the view model in a post-#9207 world. But I think we're just not ready for that yet, unfortunately.

src/cascadia/TerminalSettingsEditor/SettingContainer.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsEditor/SettingContainer.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsEditor/ViewModelHelpers.idl.h Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsEditor/pch.h Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/IInheritable.idl.h Outdated Show resolved Hide resolved
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

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

You know what, Dustin's got a lot more relevant comments than I do. If you can satisfy his concerns, I'll be happy here too

// no source; we're using the system-default value
tooltip = L"";
}
else if (const auto& profile{ settingSrc.try_as<Model::Profile>() })
Copy link
Member

Choose a reason for hiding this comment

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

I concur - almost seems like we should have ProfileSettingContainer : SettingContainer that allows for reverting to the parent, but only for settings in profiles.

All this is terrible, but let's not pretend our settings model was designed for a GUI.

@carlos-zamora
Copy link
Member Author

Main thing I'm unsure about is the macros. I've broken them up and moved them closer to where they're used. Let me know what you think.

@carlos-zamora
Copy link
Member Author

There's some weird behavior here:

  • create new profile w/ proto-extension
  • that profile has a setting "color scheme = vintage" for example
  • it appears in SUI as vintage (good)
  • weird behavior:
      1. we change vintage --> campbell
      • no reset button (by design)
      1. we set a color scheme to "solarized" in base layer
      • value is now solarized
      • no way to reset it back to vintage
      1. (do 1 and 2 concurrently)
      • reset button appears saying we're overriding base layer (good!)

@cinnamon-msft what should the proper behavior here be.

@carlos-zamora
Copy link
Member Author

Inheritance - ProtoExtension

Had to make a minor modification for proto extension. If we're specifically overriding a value from a proto-extension, we want this reset button to appear. See the demo above for what that looks like.

Design was discussed with @cinnamon-msft.

@DHowett thoughts?

Comment on lines 192 to 204
const auto profileSource{ profile.Source() };
if (profileSource == WslGeneratorNamespace ||
profileSource == AzureGeneratorNamespace ||
profileSource == PowershellCoreGeneratorNamespace)
{
// from a dynamic profile generator
return {};
}
else
{
// proto-extensions
return hstring{ fmt::format(std::wstring_view(RS_(L"SettingContainer_OverrideMessageProtoExtension")), profileSource) };
}
Copy link
Member

Choose a reason for hiding this comment

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

no.

Copy link
Member

Choose a reason for hiding this comment

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

I flatly reject a dependency from this UI element to an implementation detail in the settings model. You're going to have to find a better way to do this.

Maybe you need a "Fragment" origin.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok... can I get a bit more feedback here?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe you need to tag things that come from fragments as coming from fragments rather than coming from "Generated" to give them special behavior?

Copy link
Member

Choose a reason for hiding this comment

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

The name is not going to be particularly pretty if it comes from a package. It will say, "value from: CanonicalGroupLtd.UbuntuOnWindows_7yabmiilazx1"

Copy link
Member Author

Choose a reason for hiding this comment

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

ewwww. Understandable. Is there a way to detect that it came from a package or if it's going to have an ugly name? Maybe some way to polish the ugly name into a cleaner one?

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'm ok with doing this for now, then revisiting it after some user feedback. We're going to have to reevaluate all of this work anyways :(

@ghost ghost added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Feb 19, 2021
@DHowett
Copy link
Member

DHowett commented Feb 19, 2021

old demo-

Inheritance Demo

@DHowett
Copy link
Member

DHowett commented Feb 19, 2021

Looks like you'll have a conflict with #8414

@DHowett
Copy link
Member

DHowett commented Feb 19, 2021

Sorry, #9036.

@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Feb 19, 2021
@ghost
Copy link

ghost commented Feb 19, 2021

Hello @DHowett!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit eb0fb3e into main Feb 19, 2021
@ghost ghost deleted the dev/cazamor/sui/inheritance-hyperlinks branch February 19, 2021 23:50
@@ -590,6 +597,8 @@ void CascadiaSettings::_ParseAndLayerFragmentFiles(const std::unordered_set<std:
// (we add a new inheritance layer)
auto childImpl{ matchingProfile->CreateChild() };
childImpl->LayerJson(profileStub);
childImpl->Origin(OriginTag::Fragment);
childImpl->Source(source);
Copy link
Contributor

Choose a reason for hiding this comment

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

I removed this call in #9293, @carlos-zamora do we need it?

@ghost
Copy link

ghost commented Mar 1, 2021

🎉Windows Terminal Preview v1.7.572.0 has been released which incorporates this pull request.:tada:

Handy links:

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Settings UI Anything specific to the SUI AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants