[Mac] Fix jagged profile button text, especially with a dark theme.
This is a much-simplified version of r443707 (which was reverted).
AvatarButton's text has jagged, rainbow tinted edges. Investigation
shows that text anti-aliasing can be hinted by a view's ancestors or
direct children of its ancestors. Most view classes don't return a hint,
but NSVisualEffectView does. We have an NSVisualEffectView behind the
tab strip, but tint colors and theme backgrounds are drawn over it so
the hint is usually wrong.
A simple solution is to wrap the NSVisualEffectView in another view so
that it's not considered.
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. The effect is created by the
window server: the NSVisualEffectView cuts a hole in the window and
passes a mask to the window server, which uses the mask to render a
translucent material behind the right parts of the window.
The translucent parts of the window aren't visible to the app, and
subpixel anti-aliasing needs information about the background. Usually,
AppKit turns off subpixel AA when text is rendered over a transparent
background. Apple came up with an interesting trick to get around that
because NSVisualEffectView is used in so many places: It implements two
undocumented methods, `-shouldSetFontSmoothingBackgroundColor` and
`-_backgroundColorForFontSmoothing`. They return the basic color of the
material that the window server's going to render, and the text cell
pretends that it's over an opaque background of that color. The
translucency is subtle, so it's not obvious that anti-aliasing is done
with a fixed color.
NSView implements these methods to search its immediate subviews and
then return NO/nil if it's opaque, or recurse to its superview if not.
A quirk of this strategy is that NSVisualEffectView must be either a
superview or an immediate subview of a superview to provide a hint. So,
the AvatarButton's text does get a background color hint with the
| |- TabStripBackgroundView
…but, if the NSVisualEffectView were wrapped in another view, it doesn't
(because each step of the search just looks at immediate subviews):
| |- NSVisualEffectView
| | |- TabStripBackgroundView
With this change, AvatarButton's text is no longer subpixel
anti-aliased. That seems to be a side effect of doing custom drawing
(and it feels like a bug that it *does* get subpixel AA when
NSVisualEffectView provides a hint). Letting the NSButton draw its own
text, or drawing the text with an NSTextField, should bring it back, and
I want to make that change in a future CL.
Reviewed-by: Elly Fong-Jones <firstname.lastname@example.org>
Commit-Queue: Sidney San Martin <email@example.com>
3 files changed