Change the ControlCore layer to own a copy of its settings#11619
Conversation
…at can't be right
… a good enough start
…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
…anup of these guys.
DHowett
left a comment
There was a problem hiding this comment.
This is going out in team selfhost
|
We've been selfhosting this and I haven't run into any issues, so... gonna give it another look :) |
|
@msftbot merge this in 8 hours |
|
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:
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". |
| // is the last one out. | ||
| for (auto i{ _restorePreviewFuncs.rbegin() }; i < _restorePreviewFuncs.rend(); i++) | ||
| { | ||
| auto f = *i; |
There was a problem hiding this comment.
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 }; |
There was a problem hiding this comment.
nit: i thought having a null unfocusedAppearance would be enough
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
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
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
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
|
🎉 Handy links: |
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 aT.S.M.TerminalSettingsobject, as well as anotherTerminalSettingsobject if the user wants to have anunfocusedAppearance. 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
ControlCorein the Content Process is given a pointer to aTerminalSettingsin a certain Window Process, and that control is subsequently moved to another window, then there's no guarantee that the originalTerminalSettingsobject 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. EnterControlSettings, 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:
TerminalSettingsthat 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 layeredTerminalSettingsfor 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 aMicrosoft.Terminal.Core.Schemestruct for holding that data.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.IControlSettingsat all anymore - it initalizes itself via the settings in theCore. This will be useful for tear-out, when we need to have theTermControlinitialize itself from just aControlCore, without being able to rebuild the settings from scratch.TabTeststhat were written under the assumption that the Control had a layeredTerminalSettingsobviously broke, as they were designed to. They've been modified to reflect the new reality.UnfocusedAppearanceall at once. If we don't give it anunfocusedAppearance, it will just use the focused appearance as the unfocused appearance.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,opacityanduseAcrylic, we need to store in a handy newRUNTIME_SETTINGproperty. We can write those runtime overrides to those properties.References
PR Checklist
ICoreSettings/IControlSettingsproperties getters-only #7219Detailed 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
MockTerminalSettingsclasses used in tests to the x macros quite yet. I wanted to merge this with #11416 inmainbefore I went too crazy.Validation Steps Performed
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.