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 a profile to specify an "unfocused" appearance #8392

Merged
103 commits merged into from
Apr 8, 2021

Conversation

PankajBhojwani
Copy link
Contributor

@PankajBhojwani PankajBhojwani commented Nov 24, 2020

This pull request adds an appearance configuration object to our
settings model and app lib, allowing the control to be rendered
differently depending on its state, and then uses it to add support for
an "unfocused" appearance that the terminal will use when it's not in
focus.

To accomplish this, we isolated the appearance-related settings from
Profile (into AppearanceConfig) and TerminalSettings (into the
IControlAppearance and ICoreAppearance interfaces). A bunch of work was
done to make inheritance work.

The unfocused appearance inherits from the focused one for that
profile
. This is important: If you define a
defaults.unfocusedAppearance, it will apply all of defaults' settings to
any leaf profile when a terminal in that profile is out of focus.

Specified in #8345
Closes #3062
Closes #2316

@PankajBhojwani PankajBhojwani changed the title [DRAFT] Appearance configuration objects for profiles Appearance configuration objects for profiles Dec 11, 2020
@PankajBhojwani PankajBhojwani marked this pull request as ready for review December 11, 2020 20:31
@github-actions

This comment has been minimized.

Copy link
Member

@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.

Awesome! This is all much clearer now. Thanks you!

src/cascadia/TerminalApp/Pane.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TabManagement.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalTab.cpp Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/IInheritable.h Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/Profile.h Show resolved Hide resolved
Comment on lines +171 to +190
// Method Description:
// - Inserts a parent profile into a child profile, at the specified index if one was provided
// - Makes sure to call _FinalizeInheritance after inserting the parent
// Arguments:
// - child: the child profile to insert the parent into
// - parent: the parent profile to insert into the child
// - index: an optional index value to insert the parent into
void Profile::InsertParentHelper(winrt::com_ptr<Profile> child, winrt::com_ptr<Profile> parent, std::optional<size_t> index)
{
if (index)
{
child->InsertParent(index.value(), parent);
}
else
{
child->InsertParent(parent);
}
child->_FinalizeInheritance();
}

Copy link
Member

Choose a reason for hiding this comment

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

I guess we don't need to right now, but would it make sense to move this to IInheritable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah so we don't want every InsertParent call to call _FinalizeInheritance, that's why Profile implements a helper for it instead. (Adding _FinalizeInheritance in InsertParent will break GlobalAppSettings in the settings UI)

auto defaultChild = defaultImpl->CreateChild();
if (parent.UnfocusedSettings())
{
parent.UnfocusedSettings().SetParent(*defaultChild);
Copy link
Member

Choose a reason for hiding this comment

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

Discussed offline. Yeah, this makes sense. I guess what was confusing to me is that this function would make TerminalSettings inherit from another TerminalSettings. Here, we're doing the same thing. TerminalSettingsCreateResult is intended to just be a way to pass two objects at once. It is not inheritable, whereas TerminalSettings is.

src/cascadia/TerminalControl/TermControl.h Show resolved Hide resolved
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

Some explanation required around the locking changes. We have had no end of trouble with locking, so this seems ~ ~ dangerous ~ ~

@@ -26,6 +26,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);

winrt::fire_and_forget UpdateSettings();
winrt::fire_and_forget UpdateAppearance(const IControlAppearance newAppearance);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
winrt::fire_and_forget UpdateAppearance(const IControlAppearance newAppearance);
winrt::fire_and_forget UpdateAppearance(const IControlAppearance& newAppearance);

always one more & ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wait, we can't do this because its a fire_and_forget right?

Copy link
Member

Choose a reason for hiding this comment

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

i keep making this mistake! AGH.

// Initialization will handle the renderer settings.
return;
}
auto lock = _terminal->LockForWriting();
Copy link
Member

Choose a reason for hiding this comment

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

@PankajBhojwani yeah -- why did this lock move down?

// Initialization will handle the renderer settings.
return;
}
auto lock = _terminal->LockForWriting();
Copy link
Member

Choose a reason for hiding this comment

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

i am also very worried about the removal of the initialization check below. I didn't see it pop back up anywhere.

This lock guards access to the variable determining whether the terminal is initialized above all -- we will explode if we try to update settings while not initialized.

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Apr 7, 2021
@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Apr 7, 2021
@@ -878,6 +910,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// becomes a no-op.
this->Focus(FocusState::Programmatic);

// Now that the renderer is set up, update the appearance for initialization
UpdateAppearance(_settings);
Copy link
Member

Choose a reason for hiding this comment

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

okay, so. It looks like we're doing a bunch of other things here that are touching XAML objects. I think that initialization happens on the UI thread already. I think that we should then in this case call the "from the UI thread" version. Otherwise, we will end up in a weird place. We're literally saying... "Update the appearance after I return from this function, having unlocked the terminal lock"

I bet that that would deadlock because _UpdateAppearanceFromUIThread takes the lock.

How were the appearance settings getting applied before this? o_O

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So... I don't remember why I added this line here, and removing it doesn't cause any issues. I'm guessing this line was needed at first but somewhere down the line it wasn't required anymore and I didn't come back to update this! Its gone now :)

Copy link
Member

@DHowett DHowett 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 excited. Let's do it.

@DHowett DHowett changed the title Appearance configuration objects for profiles Add support for a profile to specify an "unfocused" appearance Apr 8, 2021
@ghost ghost added Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Issue-Task It's a feature request, but it doesn't really need a major design. labels Apr 8, 2021
@DHowett DHowett added AutoMerge Marked for automatic merge by the bot when requirements are met and removed Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Issue-Task It's a feature request, but it doesn't really need a major design. labels Apr 8, 2021
@ghost
Copy link

ghost commented Apr 8, 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
Copy link

ghost commented Apr 14, 2021

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

Handy links:

ghost pushed a commit that referenced this pull request Apr 21, 2021
## Summary of the Pull Request

Allow schemes to be previewed as the user hovers over them in the Command Palette.

![preview-set-color-scheme](https://user-images.githubusercontent.com/18356694/114557761-9a3cbd80-9c2f-11eb-987f-eb0c89ee1fa6.gif)

## References
* Branched off of #8392, which is why the commit history is so polluted. 330a8e8 : 544b2fd has the interesting commits
* #5400: cmdpal megathread

### Potential follow-ups
* changing the font size
* changing the font face
* changing the opacity of acrylic

## PR Checklist
* [x] Closes #6689, a last straggling FHL PR
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated - I don't think so

## Detailed Description of the Pull Request / Additional comments

This works by inserting a "preview" `TerminalSettings` into the settings hierarchy, before the `TermControl`'s runtime settings, and after the ones from the actual `CascadiaSettings`. This allows us to modify that preview settings object, then discard it when we're done with the preview.

This could also be used for other settings in the future - I built it to be extensible to other `ShortcutAction`s, though I haven't implemented those yet.

## Validation Steps Performed

* Select a colorscheme - it becomes the active one
* `colortool -x <scheme>` after selecting a scheme - colortool overrides the selected scheme
* Select a colorscheme after a `colortool -x <scheme>` after selecting a scheme - the scheme in the palette becomes the active one
* Pressing <kbd>esc</kbd> at any point to dismiss the command palette - scheme returns to the previous one
* reloading the settings - returns to the scheme in the settings
@ghost
Copy link

ghost commented May 25, 2021

🎉Windows Terminal v1.8.1444.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 Issues related to settings and customizability, for console or terminal 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
4 participants