Skip to content

[ENH]: macOS backend should match system app icons #31895

Open

Description

@iccir

Problem

A minor issue, but one that has bothered me for several years.

Apple switched to squircle icons with macOS Big Sur in 2020. This style persisted until macOS Tahoe in 2025, when they subtly changed the corner radius and added support for dark/clear/tinted icons.


On macOS Big Sur through macOS Sequoia, we stand out a bit:

Image

In Tahoe with dark icons enabled, we stand out a bit more:

Image

This could be a visual accessibility issue, since there's now a very-bright dot on the outskirts of your vision.


Apple locks most of the app icon appearance functionality behind private API, so perfectly matching dark/clear/tinted Tahoe icons with the operating system is prone to breakage. Even if we made an icon matching the dark Tahoe design perfectly, this would break in Golden Gate as they have changed the highlight angle.

There is also no public way to determine if the user has light/dark icons selected (a separate preference from light/dark system appearance), although there is an undocumented AppleIconAppearanceTheme setting. Using it could likely create a maintenance issue in the future.

All that said, I'd like to add macOS icons for basic light mode and dark mode.

However, I'm not sure of the exact legal issues here. There are some open issues related to Logo Usage (#18716) which seems to imply that exact color combinations should be used. However, the current macOS icon (which is rendered from matplotlib.pdf) doesn't match those specific colors.

We could match the icon closer to what is found on the main site. Something like this:

Image

(From left to right: System Settings, Preview, Matplotlib mockup, Matplotlib current, Apple's template icon. This is the Big Sur - Sequoia style, Tahoe changed these icons.)

Proposed solution

No response

Activity

  1. iccir commented on Jun 14, 2026

    @iccir
    ContributorAuthor

    Additional note: on iOS, if the operating system detects that your icon hasn't been updated to match the new guidelines, Apple will take your icon and attempt to apply glass effects to it. This has resulted in my own trademarked icons getting modified on user devices (sigh).

    macOS does something similar, which folks have referred to as "squircle jail".

    Right now, the macOS backend uses NSApplication.applicationIconImage, which bypasses squircle jail in Tahoe. However, there is no guarantee that this behavior won't change in future versions of macOS. A lot of us were hoping that Apple would relax the squircle requirement in macOS Golden Gate, but this doesn't appear to be the case.

  2. timhoffm commented on Jun 15, 2026

    @timhoffm
    Member

    I don't care too much, but if you want to make a mac icon compliant variant, go for it. You can generate appropriate logo input from
    https://matplotlib.org/stable/gallery/misc/logos2.html

  3. iccir commented on Jun 27, 2026

    @iccir
    ContributorAuthor

    My apology, I have this working in my local branch, but I forgot to update this bug with my findings.

    I did a lot of research into reversing Apple's icon metrics. In Big Sur through Sequoia, Apple provided Photoshop templates, so the metrics were easy to reverse. In Tahoe and Golden Gate, I had to write a program to "wiggle" between a blank white icon and a programmatically-generated one.

    As previously mentioned, the best that we can do is set NSApplication.applicationIconImage to an approximation. Using my linked file, an almost exact approximation can be made using these parameters:

    pre-Tahoe Tahoe / Golden Gate
    Squircle Width 206 208
    Corner Radius 45.5 54
    Shadow Opacity 0.3 0.28
    Shadow Offset 3 2
    Shadow Radius 3 5

    A few notes:

    1. The squircle shape can be matched using a CALayer with a `cornerCurve of kCACornerCurveContinuous. This API does not exist until macOS 10.15 (we support back to 10.12 currently and 10.14 after my ARC changes land)
    2. The shadow is actually an offset Gaussian Blur. There is no way to match the shadow using CGContext or CALayer drop shadow effects. The only public API for gaussian blurs is CIImage, which I strongly recommend against using due to the initialization cost of spinning up CoreImage.
    3. .icns files are rather large, especially if they contain several representations. I don't think we should have separate icon files for Sequoia Light, Sequoia Dark, Tahoe Light, Tahoe Dark, as this would likely add over a 1MB, dwarfing the size of the current image assets.

    My approach has been as follows:

    Use 6 image files: 2 content files, 2 squircle masks, 2 shadows.

    Name Description File Size
    macosx_appicon_light Content - Light 25KB
    macosx_appicon_dark Content - Dark 25KB
    macosx_appicon_mask11 Squircle Mask - macOS 11 5KB
    macosx_appicon_mask26 Squircle Mask - macOS 26 5KB
    macosx_appicon_mask11 Shadow - macOS 11 6KB
    macosx_appicon_mask26 Shadow - macOS 26 8KB

    In the macosx backend: draw a shadow, set a squircle as the mask, and then draw the content. These are all lightweight operations (it's actually more performant on my machine than trying to render the current PDF!) and the total file size is 74KB. It may be possible to configure meson to not include these files if building the Windows or Linux binaries.

    The current result of the work-in-progress:


    Sonoma + Light:

    Image

    Golden Gate + Dark:

    Image

    In both cases, the wedges of the logo follow the jet() base colors per my comment in #18716.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions