From a1a85856add3d02957233c5527e98f48721d3a9b Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 4 May 2022 09:04:16 -0400 Subject: [PATCH] Fix icon being the wrong colour on macos sometimes Signed-off-by: Sebastian Malton --- .../tray/computed-tray-icon.injectable.ts | 8 +- src/main/tray/create-tray-icon.injectable.ts | 92 +++++++++++++++++++ src/main/tray/create-tray-icon.ts | 71 -------------- 3 files changed, 95 insertions(+), 76 deletions(-) create mode 100644 src/main/tray/create-tray-icon.injectable.ts delete mode 100644 src/main/tray/create-tray-icon.ts diff --git a/src/main/tray/computed-tray-icon.injectable.ts b/src/main/tray/computed-tray-icon.injectable.ts index a00c6c28c9..b39b062dd0 100644 --- a/src/main/tray/computed-tray-icon.injectable.ts +++ b/src/main/tray/computed-tray-icon.injectable.ts @@ -11,7 +11,7 @@ import type { Disposer } from "../../common/utils"; import { getOrInsertWithAsync, HashMap } from "../../common/utils"; import updateAvailableInjectable from "../app-updater/update-available.injectable"; import useDarkColorsInjectable from "../electron/use-dark-colors.injectable"; -import { createTrayIcon } from "./create-tray-icon"; +import createTrayIconInjectable from "./create-tray-icon.injectable"; export interface ComputedTrayIcon { getCurrent(): Promise; @@ -29,15 +29,13 @@ const computedTrayIconInjectable = getInjectable({ const useDarkColors = di.inject(useDarkColorsInjectable); const updateAvailable = di.inject(updateAvailableInjectable); const logger = di.inject(loggerInjectable); + const createTrayIcon = di.inject(createTrayIconInjectable); const lock = new AwaitLock(); const cache = new HashMap( (key) => `${key.updateAvailable ? "updateAvailable" : ""}:${key.useDarkColors ? "shouldUseDarkColors" : ""}`, ); - const computedCurrent = (key: NativeImageCacheKey) => getOrInsertWithAsync(cache, key, () => createTrayIcon({ - size: 16, - ...key, - })); + const computedCurrent = (key: NativeImageCacheKey) => getOrInsertWithAsync(cache, key, () => createTrayIcon(key)); return { getCurrent: () => computedCurrent({ diff --git a/src/main/tray/create-tray-icon.injectable.ts b/src/main/tray/create-tray-icon.injectable.ts new file mode 100644 index 0000000000..03c6fffa9d --- /dev/null +++ b/src/main/tray/create-tray-icon.injectable.ts @@ -0,0 +1,92 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { nativeImage } from "electron"; +import type { NativeImage } from "electron"; +import { base64 } from "../../common/utils"; +import sharp from "sharp"; +import { JSDOM } from "jsdom"; +import LogoLens from "../../renderer/components/icon/logo-lens.svg"; +import Notice from "../../renderer/components/icon/notice.svg"; +import { getInjectable } from "@ogre-tools/injectable"; +import isMacInjectable from "../../common/vars/is-mac.injectable"; + +export interface CreateTrayIconArgs { + useDarkColors: boolean; + updateAvailable: boolean; +} + +export type CreateTrayIcon = (args: CreateTrayIconArgs) => Promise; + +const createTrayIconInjectable = getInjectable({ + id: "create-tray-icon", + instantiate: (di): CreateTrayIcon => { + const produceTemplateImage = di.inject(isMacInjectable); + + return async ({ useDarkColors, updateAvailable }) => { + const size = 32; // 2x zoom + const trayIconColor = useDarkColors ? "white" : "black"; // Invert to show contrast + const trayBackgroundColor = useDarkColors ? "black" : "white"; + const styleTag = produceTemplateImage + ? "" + : ` + + `; + + const overlayImages: sharp.OverlayOptions[] = []; + const parsedLogoSvg = base64.decode(LogoLens.split("base64,")[1]); + const logoSvgRoot = new JSDOM(parsedLogoSvg).window.document.getElementsByTagName("svg")[0]; + + logoSvgRoot.innerHTML += styleTag; + + if (updateAvailable) { + // This adds some contrast between the notice icon and the logo + logoSvgRoot.innerHTML += ``; + + const parsedNoticeSvg = base64.decode(Notice.split("base64,")[1]); + const noticeSvgRoot = new JSDOM(parsedNoticeSvg).window.document.getElementsByTagName("svg")[0]; + + noticeSvgRoot.innerHTML += styleTag; + + const noticeImage = await sharp(Buffer.from(noticeSvgRoot.outerHTML)) + .resize({ + width: Math.floor(size/1.5), + height: Math.floor(size/1.5), + }) + .toBuffer(); + + overlayImages.push({ + input: noticeImage, + top: Math.floor(size/2.5), + left: Math.floor(size/2.5), + }); + } + + const iconBuffer = await sharp(Buffer.from(logoSvgRoot.outerHTML)) + .composite(overlayImages) + .resize({ width: size, height: size }) + .png() + .toBuffer(); + const image = nativeImage.createFromBuffer(iconBuffer, { + scaleFactor: 2, + }); + + image.setTemplateImage(produceTemplateImage); + + return image; + }; + }, +}); + +export default createTrayIconInjectable; + diff --git a/src/main/tray/create-tray-icon.ts b/src/main/tray/create-tray-icon.ts deleted file mode 100644 index e7ec099ba4..0000000000 --- a/src/main/tray/create-tray-icon.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { nativeImage } from "electron"; -import type { NativeImage } from "electron"; -import { base64 } from "../../common/utils"; -import sharp from "sharp"; -import { JSDOM } from "jsdom"; -import LogoLens from "../../renderer/components/icon/logo-lens.svg"; -import Notice from "../../renderer/components/icon/notice.svg"; - -export interface CreateTrayIconArgs { - useDarkColors: boolean; - size: number; - updateAvailable: boolean; -} - -export async function createTrayIcon({ useDarkColors, size, updateAvailable }: CreateTrayIconArgs): Promise { - const trayIconColor = useDarkColors ? "white" : "black"; // Invert to show contrast - const trayBackgroundColor = useDarkColors ? "black" : "white"; - const styleTag = ` - - `; - - const overlayImages: sharp.OverlayOptions[] = []; - const parsedLogoSvg = base64.decode(LogoLens.split("base64,")[1]); - const logoSvgRoot = new JSDOM(parsedLogoSvg).window.document.getElementsByTagName("svg")[0]; - - logoSvgRoot.innerHTML += styleTag; - - if (updateAvailable) { - // This adds some contrast between the notice icon and the logo - logoSvgRoot.innerHTML += ``; - - const parsedNoticeSvg = base64.decode(Notice.split("base64,")[1]); - const noticeSvgRoot = new JSDOM(parsedNoticeSvg).window.document.getElementsByTagName("svg")[0]; - - noticeSvgRoot.innerHTML += styleTag; - - const noticeImage = await sharp(Buffer.from(noticeSvgRoot.outerHTML)) - .resize({ - width: Math.floor(size/1.5), - height: Math.floor(size/1.5), - }) - .toBuffer(); - - overlayImages.push({ - input: noticeImage, - top: Math.floor(size/2.5), - left: Math.floor(size/2.5), - }); - } - - const iconBuffer = await sharp(Buffer.from(logoSvgRoot.outerHTML)) - .composite(overlayImages) - .resize({ width: size, height: size }) - .png() - .toBuffer(); - - return nativeImage.createFromBuffer(iconBuffer); -}