macOS Rework: App Icon - #32361
Draft
iccir wants to merge 22 commits into
Draft
macOS Rework: App Icon#32361iccir wants to merge 22 commits into
iccir wants to merge 22 commits into
Conversation
Obj-C classes: MatplotlibAppDelegate -> MPLLegacyAppDelegate Window -> MPLLegacyWindow View -> MPLLegacyView NavigationToolbar2Handler -> MPLLegacyNavigationToolbar2Handler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR summary
Important
This PR depends on #32161 and will appear larger than it really is until #32161 is merged. To view the actual changes in this PR, compare macos-staging → macos-pr-appicon.
This PR matches the app icon of the macOS backend to the shape and style of other system icons. To help with visual accessibility, the user can choose either a light icon or a dark icon.
Due to limitations in Apple's API, we cannot match "clear" or "tinted" app icons, nor can we automatically match the user's selected icon appearance preference.
Closes #31895
Overview
Starting in macOS 26, developers are suppose to use Icon Composer to create app icons. When an app is built, Xcode uses the Icon Composer document to generate and bundle rasterized images. At runtime, these images are layered and tinted to match the user's icon appearance preference.
This approach is not an option for us:
Apple only provides one other option: use
-[NSApplication setApplicationIconImage:]and provide an image at runtime.What's In-Scope and Out-of-Scope
I believe that:
However:
Thus, the "clear" and "tinted" styles are impossible to match. We also cannot query the system to see if the user prefers "light" or "dark".
To compensate, I've added a new
macos.app_iconrcparam. This defaults tolightbut can be set todarkif a user is sensitive to bright content. If Apple ever adds the relevant API, we could someday have asystemoption.Reverse-engineering the Icon Metrics
Apple provides no documentation on the exact metrics used by their icons. I had to create AppIconReverser to figure these out:
This app also exports the dark background which macOS 26 and 27 programmatically generate. While not specifically needed for accessibility, we should match the other icons as much as possible.
Variants
The permutation of shape and appearance results in five icon variants:
If we stored each variant as a composited PNG, they would be 35-50KB each (175-250KB total). Instead, we build them at runtime from separate files:
Together, these total 75KB. There is very little performance penalty with compositing them together at launch. If Apple changes the icon size or dark background style in a future version of macOS, we only suffer a small size penalty.
Note
My hope is that the macOS icon design will stabilize with macOS 27. We can always switch to a dark gradient if it becomes a burden - it won't perfectly match, but it will still help with visual accessibility.
Making the Icon Pieces
Except for
*_bgdark*.png, the above files are generated via two tools:Originally, I intended for the logo PNG files to be generated from a source SVG with tweakable colors via CSS variables and
color-mix(). Unfortunately, Inkscape and other SVG renderers provide very little support for modern SVG features. Only a real web browser engine like headless Chromium can pull this off. I didn't want to add another dependency, so I opted to have the Python script generate Inkscape-compatible SVG files.Compositing the Icon
_init_macos()gathers all paths in "mpl-data" which matchmacos_*.png. It sends these along with ause_dark_appiconboolean to the Objective-C layer.-[MPLAppDelegate _buildAppIcon]to build the actual icon. The actual compositing process is as follows:CGContextDrawImage()with the shadow.CGContextClipToMask()with the mask.CGContextDrawImage()with the background or draw a dark gradient.CGContextDrawImage()with the content image.-[NSApplication setApplicationIconImage:].AI Disclosure
PR quality check