Chromium Code Reviews
Description[Mac] Fix rough-looking profile picker text, especially with a dark theme.
Issue 593835 shows the AvatarButton's text having jagged, rainbow tinted
edges. It turns out that the text cell gets a hint about anti-aliasing
from the NSVisualEffect view below it, but the hint is wrong because the
NSVisualEffectView is itself below the theme background.
This only happens when the NSVisualEffectView's blendingMode is set to
NSVisualEffectBlendingModeBehindWindow (which makes the content behind
the window show through with a blur effect). To create the effect, the
view cuts a hole in the window and generates a mask which the window
server uses to render a translucent material behind the window.
Because the translucent parts of the window are invisible to the app,
the text can't render itself with correct subpixel anti-aliasing, which
needs information about the background. To help, NSVisualEffectView
implements two undocumented methods:
`-shouldSetFontSmoothingBackgroundColor` and
`-_backgroundColorForFontSmoothing`. It provides the base color of the
translucent material, and for the purpose of antialiasing the text cell
pretends that it's over an opaque background of that color. Because the
translucency effect is subtle, it's not obvious that the antialiasing is
done with a fixed color.
NSView implements these methods to first search its immediate subviews
and return the first YES/non-nil answer, or return NO/nil if
`self.opaque == YES`, then tail call the same method on its superview.
A quirk of this strategy is that, to provide a background color to a
text view, an NSVisualEffectView must be either a superview or an
immediate subview of a superview. So, the AvatarButton's text does get a
background color hint with the current hierarchy:
- NSThemeFrame
|- NSVisualEffectView
| |- TabStripBackgroundView
|- FullSizeContentView
|- AvatarButton
…but, if the NSVisualEffectView were wrapped in another view, it doesn't
(because each step of the search just looks at immediate subviews):
- NSThemeFrame
|- NSView
| |- NSVisualEffectView
| | |- TabStripBackgroundView
|- FullSizeContentView
|- AvatarButton
Anyway, back on topic, our issue is that the text cell accepts the
hinted background color, which is never right since Chrome always
draws a tint over the visual effect view, and in some cases the hint is
drastically wrong.
Ideally, we'd provide a fake background for the text to perform subpixel
anti-aliasing against, but it's unclear how to do that. For now, the
simplest solution is to wrap it in another view.
This CL sucks all of the tab strip background drawing into
TabStripBackgroundView, and makes it so that other views don't need to
know about the NSVisualEffectView at all.
It also only creates the NSVisualEffectView when it's used, and gets rid
of it when it's not used (like in full screen, or when a theme is
installed).
BUG=593835
Review-Url: https://codereview.chromium.org/2430493002
Cr-Commit-Position: refs/heads/master@{#443707}
Committed: https://chromium.googlesource.com/chromium/src/+/a5fd3c415f3cc4f8813ba9772d838bee41040ae8
Patch Set 1 #Patch Set 2 : Rebase/refactor/finish #Patch Set 3 : Add a missing header to a test. #Patch Set 4 : Roll back a change that broke tests and shouldn't have been in this CL anyway :) #Patch Set 5 : Replace a now-invalid test with a better one. #Patch Set 6 : Add theme tests #
Total comments: 43
Patch Set 7 : Address a round of comments. #
Total comments: 14
Patch Set 8 : Address second round of comments. #Patch Set 9 : Scopify! #Messages
Total messages: 57 (43 generated)
|