-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Move the common render settings into a shared class #12127
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome step forward. I admit that IRenderData
was probably not my best idea ever, but oh well. Thanks as always @j4james.
SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DARK_WHITE); | ||
SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DARK_BLACK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really love this idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
color aliases are clever as. Thanks
@@ -250,17 +250,14 @@ void Registry::LoadFromRegistry(_In_ PCWSTR const pwszConsoleTitle) | |||
|
|||
// Now load complex properties | |||
// Some properties shouldn't be filled by the registry if a copy already exists from the process start information. | |||
DWORD dwValue; | |||
const auto loadDWORD = [=](const auto valueName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I love it. But I do wonder if we should just be making it into a first-class function or template citizen instead of just a lambda. It sure cleans up the below calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I did consider this, but pulling it out into a first-class function means you need to pass additional parameters that you get for free with the lambda, so it's not quite as clean. I do think perhaps there's potential for a nicer registry encapsulation class here that could clean up more of the code, but I didn't want to get too sidetracked in this PR, and the lambda at least doesn't make things a whole lot worse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I almost broke down and worked on better-encapsulating the registry code some time a few years back when I first saw this file . . . so yeah, I get that for sure :D
{ | ||
_pSettings->SetCodePage(dwValue); | ||
_pSettings->SetCodePage(codePage.value()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to say "what about the exception" but I guess the if
has got you covered on that as it will test false
. Nice.
@@ -61,10 +61,7 @@ const RegistrySerialization::_RegPropertyMap RegistrySerialization::s_PropertyMa | |||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_INTERCEPTCOPYPASTE, SET_FIELD_AND_SIZE(_fInterceptCopyPaste) }, | |||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_TERMINALSCROLLING, SET_FIELD_AND_SIZE(_TerminalScrolling) }, | |||
{ _RegPropertyType::Dword, CONSOLE_REGISTRY_USEDX, SET_FIELD_AND_SIZE(_fUseDx) }, | |||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) }, | |||
{ _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTFOREGROUND, SET_FIELD_AND_SIZE(_colorTable[TextColor::DEFAULT_FOREGROUND]) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps leave a comment that some of these have disappeared as the model has changed as I think this table was a semi-definitive list of what we were messing with in terms of values under HKCU\Console
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've added a comment at the bottom of the list noting all the settings that are not included. There was already also a comment at the top noting that the list is incomplete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have slightly mixed feelings about this PR. I can't quite put my finger on it, but I feel like there's some way to make our entire color handling a lot simpler and involve less classes. We have quite a lot of code to represent colors and metadata don't we? 😅
However this PR seems like the absolutely right approach anyways because it simplifies and "unifies" a ton of code. Nice! I left some thoughts you can consider before we merge this later.
Yeah, I feel the same way. I know this is far from perfect but I'm hoping it's at least moving us in the right direction, and we'll still be able to improve things over time. I should add that my initial plan was to try add these properties directly to the renderer, so there wouldn't have been a need for another class, but that ended up being unworkable without essentially rewriting everything everywhere. So this was a bit of a compromise, which is not as neat as I would liked, but still achieved most of my goals. |
FYI, I've merged my local branch with main to resolve the conflicts, but there are some tests that are failing now, and I'm still trying to establish the cause. |
I think the merge is good. Test failures were the result of a previous commit. I've raised another issue for that (#12158). |
Hello @lhecker! Because this pull request has the 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 (
|
// color pair to the adjusted foreground for that color pair | ||
void RenderSettings::MakeAdjustedColorArray() noexcept | ||
{ | ||
// The color table has 16 colors, but the adjusted color table needs to be 18 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I believe that we now calculate this for everyone, even if the feature isn't being used -- that might have a cost in conhost that we don't want to take on, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested this PR locally before approving it. I found no regressions. Binary size (without PGO) only increased ever so slightly (~500 Byte).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Post-merge review: I love it! I'm v. happy with this. Thank you!)
🎉 Handy links: |
Summary of the Pull Request
This PR moves the color table and related render settings, which are common to both conhost and Windows Terminal, into a shared class that can be accessed directly from the renderer. This avoids the overhead of having to look up these properties via the
IRenderData
interface, which relies on inefficient virtual function calls.This also introduces the concept of color aliases, which determine the position in the color table that colors like the default foreground and background are stored. This allows the option of mapping them to one of the standard 16 colors, or to have their own separate table entries.
References
This is a continuation of the color table refactoring started in #11602 and #11784. The color alias functionality is a prerequisite for supporting a default bold color as proposed in #11939. The color aliases could also be a way for us to replace the PowerShell color quirk for #6807.
PR Checklist
Detailed Description of the Pull Request / Additional comments
In addition to the color table, this new
RenderSettings
class manages the blinking state, the code for adjusting indistinguishable colors, and various boolean properties used in the color calculations. These boolean properties are now stored in atil::enumset
so they can all be managed through a singleSetRenderMode
API, and easily extended with additional modes that we're likely to need in the future.In Windows Terminal we have an instance of
RenderSettings
stored in theTerminal
class, and in conhost it's stored in theSettings
class. In both cases, a reference to this class is passed to theRenderer
constructor, so it now has direct access to that data. The renderer can then pass that reference to the render engines where it's needed in theUpdateDrawingBrushes
method.This means the renderer no longer needs the
IRenderData
interface to access theGetAttributeColors
,GetCursorColor
, orIsScreenReversed
methods, so those have now been removed. We still need access toGetAttributeColors
in certain accessibility code, though, so I've kept that method in theIUIAData
interface, but the implementation just forwards to theRenderSettings
class.The implementation of the
RenderSettings::GetAttributeColors
method is loosely based on the originalTerminal
code, only theCalculateRgbColors
call has now been incorporated directly into the code. This let us deduplicate some bits that were previously repeated in the section for adjusting indistinguishable colors. The last steps, where we calculate the alpha components, have now been split in to a separateGetAttributeColorsWithAlpha
method, since that's typically not needed.Validation Steps Performed
There were quite a lot changes needed in the unit tests, but they're mostly straightforward replacements of one method call with another.
In the
TextAttributeTests
, where we were previously testing theCalculateRgbColors
method, we're now running those tests thoughRenderSettings::GetAttributeColors
, which incorporates the same functionality. The only complication is when testing theIntenseIsBright
option, that needs to be set with an additionalSetRenderMode
call where previously it was just a parameter onCalculateRgbColors
.In the
ScreenBufferTests
andTextBufferTests
, calls toLookupAttributeColors
have again been replaced by theRenderSettings::GetAttributeColors
method, which serves the same purpose, and calls toIsScreenReversed
have been replaced with an appropriateGetRenderMode
call. In theVtRendererTests
, all the calls toUpdateDrawingBrushes
now just need to be passed a reference to aRenderSettings
instance.