diff --git a/apps/desktop/assets/trayTemplate.png b/apps/desktop/assets/trayTemplate.png
index 8d0b0411..86649747 100644
Binary files a/apps/desktop/assets/trayTemplate.png and b/apps/desktop/assets/trayTemplate.png differ
diff --git a/apps/desktop/assets/trayTemplate.svg b/apps/desktop/assets/trayTemplate.svg
index fb053ca9..f48eb6f9 100644
--- a/apps/desktop/assets/trayTemplate.svg
+++ b/apps/desktop/assets/trayTemplate.svg
@@ -1,5 +1,5 @@
diff --git a/apps/desktop/assets/trayTemplate@2x.png b/apps/desktop/assets/trayTemplate@2x.png
index 806cb591..0105fff1 100644
Binary files a/apps/desktop/assets/trayTemplate@2x.png and b/apps/desktop/assets/trayTemplate@2x.png differ
diff --git a/apps/desktop/src/main/tray-icon.test.mjs b/apps/desktop/src/main/tray-icon.test.mjs
index f04e43aa..a85ba972 100644
--- a/apps/desktop/src/main/tray-icon.test.mjs
+++ b/apps/desktop/src/main/tray-icon.test.mjs
@@ -32,18 +32,20 @@ describe("trayIconPath", () => {
})).toBe("/resources/web/pwa-192x192.png");
});
- test("uses a larger menu-bar cat instead of the padded brand mark", () => {
+ test("uses a heavier 22pt menu-bar cat instead of the padded brand mark", () => {
const svg = readFileSync(new URL("../../assets/trayTemplate.svg", import.meta.url), "utf8");
expect(svg).not.toContain("M9 2h14a6 6 0 0 1 6 6v16a6 6 0 0 1-6 6H9");
expect(svg).not.toContain("scale(0.74234234)");
expect(svg).toContain("viewBox=\"0 0 1024 1024\"");
expect(svg).toContain("fill=\"#000000\"");
- expect(svg).toContain("scale(1.22)");
+ expect(svg).toContain("stroke=\"#000000\"");
+ expect(svg).toContain("stroke-width=\"36\"");
+ expect(svg).toContain("scale(1.1)");
});
test.each([
- ["trayTemplate.png", 16, 72],
- ["trayTemplate@2x.png", 32, 144],
+ ["trayTemplate.png", 22, 72],
+ ["trayTemplate@2x.png", 44, 144],
])("%s is a crisp black template glyph", async (name, size, density) => {
const path = fileURLToPath(new URL(`../../assets/${name}`, import.meta.url));
const image = sharp(path);
@@ -65,7 +67,7 @@ describe("trayIconPath", () => {
hasAlpha: true,
});
expect(soft).toBe(0);
- expect(coverage).toBeGreaterThan(0.12);
+ expect(coverage).toBeGreaterThan(0.22);
expect(coverage).toBeLessThan(0.4);
});
});
diff --git a/scripts/prepare-desktop-icons.mjs b/scripts/prepare-desktop-icons.mjs
index a0969b92..718eb226 100644
--- a/scripts/prepare-desktop-icons.mjs
+++ b/scripts/prepare-desktop-icons.mjs
@@ -62,14 +62,19 @@ const writeResizedPng = async (sourceBuffer, size, destination) => {
const TRAY_TEMPLATE_ALPHA_THRESHOLD = 80;
const TRAY_MARK_CENTER = { x: 627, y: 580 };
-const TRAY_MARK_SCALE = 1.22;
+// 22pt matches other macOS menu-bar extras. A round stroke adds ink so the
+// open cat face keeps up with filled marks like Notion and WeChat.
+export const TRAY_MARK_SCALE = 1.1;
+export const TRAY_MARK_STROKE_WIDTH = 36;
+export const TRAY_TEMPLATE_SIZE = 22;
+export const TRAY_TEMPLATE_SIZE_2X = 44;
export const buildMacTrayTemplateSvg = (markSvg) => {
const pathMatch = markSvg.match(/]*\sd="([^"]+)"/);
if (!pathMatch) throw new Error("Brand mark is missing a path");
return `
`;
@@ -109,8 +114,8 @@ export const prepareTrayIcons = async ({
.toFile(join(assetsDirectory, fileName));
};
- await render(16, 72, "trayTemplate.png");
- await render(32, 144, "trayTemplate@2x.png");
+ await render(TRAY_TEMPLATE_SIZE, 72, "trayTemplate.png");
+ await render(TRAY_TEMPLATE_SIZE_2X, 144, "trayTemplate@2x.png");
console.log("[prepare-desktop-icons] wrote macOS tray template icons from the brand mark");
};