Skip to content

Change the ControlCore layer to own a copy of its settings#11619

Merged
62 commits merged intomainfrom
dev/migrie/oop/ragnarok
Dec 1, 2021
Merged

Change the ControlCore layer to own a copy of its settings#11619
62 commits merged intomainfrom
dev/migrie/oop/ragnarok

Conversation

@zadjii-msft
Copy link
Member

@zadjii-msft zadjii-msft commented Oct 26, 2021

Summary of the Pull Request

Currently, the TermControl and ControlCore recieve a settings object that implements IControlSettings. They use for this for both reading the settings they should use, and also storing some runtime overrides to those settings (namely, Opacity). The object they recieve currently is a T.S.M.TerminalSettings object, as well as another TerminalSettings object if the user wants to have an unfocusedAppearance. All these are all hosted in the same process, so everything is fine and dandy.

With the upcoming move to having the Terminal split into multiple processes, this will no longer work. If the ControlCore in the Content Process is given a pointer to a TerminalSettings in a certain Window Process, and that control is subsequently moved to another window, then there's no guarantee that the original TerminalSettings object continues to exist. In this scenario, when window 1 is closed, now the Core is unable to read any settings, because the process that owned that object no longer exists.

The solution to this issue is to have the ControlCore's own their own copy of the settings they were created with. that way, they can be confident those settings will always exist. Enter ControlSettings, a dumb struct for just storing all the contents of the Settings. I used x-macros for this, so that we don't need to copy-paste into this file every time we add a setting.

Changing this has all sorts of other fallout effects:

  • Previewing a scheme/anything is a tad bit more annoying. Before, we could just sneak the previewed scheme into a TerminalSettings that lived between the settings we created the control with, and the settings they were actually using, and it would just work. Even explaining that here, it sounds like magic, because it was. However, now, the TermControl can't use a layered TerminalSettings for the settings anymore. Now we need to actually read out the current color table, and set the whole scheme when we change it. So now there's also a Microsoft.Terminal.Core.Scheme struct for holding that data.
    • Why a struct? Because that will go across the process boundary as a blob, rather than as a pointer to an object in the other process. That way we can transit the whole struct from window to core safely.
  • A TermControl doesn't have a IControlSettings at all anymore - it initalizes itself via the settings in the Core. This will be useful for tear-out, when we need to have the TermControl initialize itself from just a ControlCore, without being able to rebuild the settings from scratch.
  • The TabTests that were written under the assumption that the Control had a layered TerminalSettings obviously broke, as they were designed to. They've been modified to reflect the new reality.
  • When we initialize the Control, we give it the settings and the UnfocusedAppearance all at once. If we don't give it an unfocusedAppearance, it will just use the focused appearance as the unfocused appearance.
  • The Control no longer can write settings to the ControlSettings. We don't want to be storing things in there. Pretty much everything we set in the control, we store somewhere other than in the settings object itself. However, opacity and useAcrylic, we need to store in a handy new RUNTIME_SETTING property. We can write those runtime overrides to those properties.
  • We no longer store the color scheme for a pane in the persisted state. I'm tracking that in megathread: Window State Persistence #9800. I don't think it's too hard to add back, but I wanted this in front of eyes sooner than later.

References

PR Checklist

Detailed Description of the Pull Request / Additional comments

Along the way I tried to clean up code where possible, but not too agressively.

I didn't end up converting the various MockTerminalSettings classes used in tests to the x macros quite yet. I wanted to merge this with #11416 in main before I went too crazy.

Validation Steps Performed

  • Scheme previewing works
  • Adjusting the font size works
  • focused/unfocused appearances still work
  • mouse-wheeling opacity still works
  • acrylic & cleartype still does the right thing
  • saving the settings still works
  • going wild on sliding the opacity slider in the settings doesn't crash the terminal
  • toggling retro effects with a keybinding still works
  • toggling retro effects with the command palette works
  • The matrix of (useAcrylic(true,false))x(opacity(50,100))x(antialiasingMode(cleartype, grayscale)) works as expected. Slightly changed, falls back to grayscale more often, but looks more right.

…hing. Idk, I wrote this a few days ago, I just need this clone for testing so `git commit`
…ut UpdateAppearance ends up getting called immediately after so it blows it away. Dustin had a crazy idea...
    and as soon ad I typed that out I realized that WINRT_PROPERTY already has
    setters and setting an optional override gets me nothing

    sure I could stealth the new value in underneath the runtime value, so
    reloading the settings doesn't reset font size, colors, etc

    I could

    but it sure does feel like overkill for "refactor but don't change anything"
…backgrounds and now they're totally transparent
@carlos-zamora carlos-zamora removed their assignment Nov 17, 2021
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.

This is going out in team selfhost

@DHowett
Copy link
Member

DHowett commented Nov 29, 2021

We've been selfhosting this and I haven't run into any issues, so... gonna give it another look :)

@zadjii-msft
Copy link
Member Author

@msftbot merge this in 8 hours

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

ghost commented Dec 1, 2021

Hello @zadjii-msft!

Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:

  • I won't merge this pull request until after the UTC date Wed, 01 Dec 2021 19:33:28 GMT, which is in 8 hours

If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you".

@ghost ghost merged commit 094273b into main Dec 1, 2021
@ghost ghost deleted the dev/migrie/oop/ragnarok branch December 1, 2021 19:33
// is the last one out.
for (auto i{ _restorePreviewFuncs.rbegin() }; i < _restorePreviewFuncs.rend(); i++)
{
auto f = *i;
Copy link
Member

Choose a reason for hiding this comment

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

nit: this does a copy whereas f->operator()() does not

private:
winrt::com_ptr<ControlAppearance> _unfocusedAppearance{ nullptr };
winrt::com_ptr<ControlAppearance> _focusedAppearance{ nullptr };
bool _hasUnfocusedAppearance{ false };
Copy link
Member

Choose a reason for hiding this comment

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

nit: i thought having a null unfocusedAppearance would be enough

ghost pushed a commit that referenced this pull request Jan 7, 2022
This PR makes sure profile appearances in SUI set both focused and unfocused members of the control. I totally forgot about the fact that the control is _unfocused_ in the SUI. Verified manually, I didn't think it deserved a gif.

* regressed in #11619
* Closes #11893
* I work here
ghost pushed a commit that referenced this pull request Jan 12, 2022
When I added these macros in #11619, the real purpose was to make sure we don't forget to add new settings to these test mocks as well. However, I totally forgot to convert those. I guess that happens with a 1300 line diff ¯\\\_(ツ)_/¯

* [x] Is a codehealth thing
* [x] I work here
* [x] tests still pass
zadjii-msft added a commit that referenced this pull request Jan 25, 2022
More fallout from the settings refactor. Probably because testing on a Windows
10 device is hard, because you actually need a physical machine to get acrylic
to behave correctly.

Basically, the code is simpler now, but we missed the windows 10 only edge case
where acrylic can get turned on, but we forget to enable the acrylic brush, so
it just stays off.

Refer to #11619 where this regressed, and #11643, #12229, because this is just a
hard problem apparently

* [x] Closes #11743. Technically OP is complaining about behavior that's
  by-design, but it made me realize this regressed in 1.12.
* [ ] No tests on this part of the TermControl unfortunately.
* [x] Hauled out my old Win10 laptop to verify that opacity works right:
  - [x] A fresh profile isn't created with any opacity
  - [x] Mouse wheeling turns on acrylic
  - [x] Using `opacity` only in the settings still stealthily enables acrylic
zadjii-msft added a commit that referenced this pull request Jan 25, 2022
More fallout from the settings refactor. Probably because testing on a Windows
10 device is hard, because you actually need a physical machine to get acrylic
to behave correctly.

Basically, the code is simpler now, but we missed the windows 10 only edge case
where acrylic can get turned on, but we forget to enable the acrylic brush, so
it just stays off.

Refer to #11619 where this regressed, and #11643, #12229, because this is just a
hard problem apparently

* [x] Closes #11743. Technically OP is complaining about behavior that's
  by-design, but it made me realize this regressed in 1.12.
* [ ] No tests on this part of the TermControl unfortunately.
* [x] Hauled out my old Win10 laptop to verify that opacity works right:
  - [x] A fresh profile isn't created with any opacity
  - [x] Mouse wheeling turns on acrylic
  - [x] Using `opacity` only in the settings still stealthily enables acrylic
ghost pushed a commit that referenced this pull request Jan 26, 2022
More fallout from the settings refactor. Probably because testing on a Windows
10 device is hard, because you actually need a physical machine to get acrylic
to behave correctly.

Basically, the code is simpler now, but we missed the windows 10 only edge case
where acrylic can get turned on, but we forget to enable the acrylic brush, so
it just stays off.

Refer to #11619 where this regressed, and #11643, #12229, because this is just a
hard problem apparently

* [x] Closes #11743. Technically OP is complaining about behavior that's
  by-design, but it made me realize this regressed in 1.12.
* [ ] No tests on this part of the `TermControl` unfortunately.
* [x] Hauled out my old Win10 laptop to verify that opacity works right:
  - [x] A fresh profile isn't created with any opacity
  - [x] Mouse wheeling turns on acrylic
  - [x] Using `opacity` only in the settings still stealthily enables acrylic
@ghost
Copy link

ghost commented Feb 3, 2022

🎉Windows Terminal Preview v1.13.10336.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-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Issue-Task It's a feature request, but it doesn't really need a major design. Priority-3 A description (P3) Product-Terminal The new Windows Terminal.

Projects

None yet

5 participants