Jeff Johnson (My apps, PayPal.Me, Mastodon)

How Safari (insanely) displays app extension icons

November 29 2024

I'm not talking about the tint of the extension icons this time. I'm talking about the size of the extension icons in the Safari toolbar on Mac. I've explained the difference between Safari app extensions and Safari web extensions before, so I won't repeat the explanation here, except to note that my own StopTheMadness Pro and StopTheScript are examples of Safari app extensions.

According to the Apple developer documentation, the toolbar icon of a Safari app extension should be "a scalable PDF image. The image must be transparent." If you create a new Safari app extension project in Xcode, it comes with a default extension icon, a 16x16 image in pdf format. I believe that this size is actually outdated now. A few years ago I wrote in a blog post about Safari web extension development,

On macOS Big Sur, the toolbar shows the 38x38 retina and 19x19 non-retina icon sizes, while on macOS Mojave, the toolbar shows the 32x32 retina and 16x16 non-retina icon sizes. I believe that these sizes are determined by Safari's toolbarItemIdealPointSize private method.

One of the most useful tools for investigating icon sizes is Pixie app, which is included in the Xcode Additional Tools download. Pixie zooms in on the area of your screen under the pointer, showing the individual pixels, which you can then count. Using Pixie, I discovered that all app extension icons in the Safari toolbar are also 19x19 (38x38 retina), not 16x16 (32x32). This appears to be totally undocumented by Apple, of course.

The undocumented change of extension icon size is annoying but not insane. What's insane is how Safari produces a 19x19 icon from the image file. The context for this insanity is that StopTheMadness Pro version 12.0 introduced a new Safari extension toolbar icon, but some customers immediately complained that the new icon was too large, so I was attempting to make it smaller.

After a lot of trial and error, I finally figured out the algorithm used by Safari. It turns out that Safari ignores any margins in the image file. Instead, Safari looks for nontransparent pixels in the image file, measuring the width as the distance between the leftmost and rightmost nontransparent pixels and the height as the distance between the topmost and bottommost nontransparent pixels. Safari then takes the square size of the image to be the larger of the width or height. Finally, Safari scales that square subarea of the image file to 19x19 (38x38 retina).

Thus, if you have a 16x16 pdf containing a 14x14 image with 1 pixel margins on all sides, Safari will cut out the 14x14 area and scale it up to 19x19. Likewise, if you have a 19x19 pdf containing a 15x15 image with 2 pixel margins on all sides, Safari will cut out the 15x15 area and scale it up to 19x19, even though the pdf was already 19x19.

Needless to say, Safari's behavior is nonideal for several reasons. It goes against the design of the icon creator, who included margins for a reason. Upscaling images can make them look distorted, or at least not as sharp. And Safari's own built-in toolbar icons are invariably smaller, which makes the Safari extension toolbar icons look oversized and out of place. (This is exacerbated by the tint that Safari applies to enabled Safari extension icons.) For example, the Safari back and forward arrows are only 29 pixels tall on retina and the Show sidebar button only 31, rather than 38. Even the Share button is not quite full height, 37 retina pixels from top to bottom.

Is there a workaround? Fortunately, yes. I used the workaround in StopTheMadness Pro version 12.1. Its Mac Safari toolbar icon is a 19x19 scalable pdf containing a 15x15 image with 2 pixel margins on all sides. However, the margins are very subtly off-white, in a way that the human eye can't discern. Nonetheless, that's sufficient to register as nontransparent to Safari and cause it to compute the image size as 19x19 rather than 15x15, thereby preserving the margins when the icon is displayed in the toolbar.

What an ordeal it was, though, to discover Safari's insane algorithm and the workaround for it. Hopefully this blog post is helpful to other Safari app extension developers. I've looked at a couple extensions, and I notice that Safari is indeed upscaling their toolbar icons, whether they realize it or not.

Jeff Johnson (My apps, PayPal.Me, Mastodon)