[Mac] Fix jagged profile button text, especially with a dark theme

Desktop / Chromium - Sidney San Martín [chromium.org] - 19 June 2017 11:20 EDT

This is a much-simplified version of r443707 (which was reverted).

## Summary 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.

## Details 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 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

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.

Bug: 593835 Change-Id: I06609ff4117a7a0705ad34165be4cd44e50f69b8 Reviewed-on: https://chromium-review.googlesource.com/538340

470096a [Mac] Fix jagged profile button text, especially with a dark theme.
chrome/browser/ui/cocoa/tabs/tab_strip_view.mm | 19 ++-------------
.../browser/ui/cocoa/tabs/tab_window_controller.h | 1 +
.../browser/ui/cocoa/tabs/tab_window_controller.mm | 27 ++++++++++++++++------
3 files changed, 23 insertions(+), 24 deletions(-)

Upstream: git.chromium.org

  • Share