diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-02-02 16:51:31 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-02-03 13:56:03 +0100 |
| commit | 62291d7d143547d53b38580e9d54e3810bfd97a5 (patch) | |
| tree | 9c9525da05b2844218cb964731a3d64b9d58a27b | |
| parent | 3289f39944593c7ca063c72ec2d27563ff390a09 (diff) | |
| download | mullvadvpn-62291d7d143547d53b38580e9d54e3810bfd97a5.tar.xz mullvadvpn-62291d7d143547d53b38580e9d54e3810bfd97a5.zip | |
Use path for app icon instead of data url
| -rw-r--r-- | gui/src/main/index.ts | 4 | ||||
| -rw-r--r-- | gui/src/main/linux-desktop-entry.ts | 34 | ||||
| -rw-r--r-- | gui/src/main/linux-split-tunneling.ts | 24 |
3 files changed, 41 insertions, 21 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 2fe32a0d16..b3e2ef0e10 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -55,7 +55,7 @@ import { ConnectionObserver, DaemonRpc, SubscriptionListener } from './daemon-rp import { InvalidAccountError } from './errors'; import Expectation from './expectation'; import GuiSettings from './gui-settings'; -import { getAppIcon } from './linux-desktop-entry'; +import { findIconPath } from './linux-desktop-entry'; import { backupLogFile, cleanUpLogDirectory, @@ -1506,7 +1506,7 @@ class ApplicationMain { case 'linux': return new BrowserWindow({ ...options, - icon: await getAppIcon('mullvad-vpn'), + icon: await findIconPath('mullvad-vpn'), }); default: { diff --git a/gui/src/main/linux-desktop-entry.ts b/gui/src/main/linux-desktop-entry.ts index a2712bb7e3..350035d657 100644 --- a/gui/src/main/linux-desktop-entry.ts +++ b/gui/src/main/linux-desktop-entry.ts @@ -39,14 +39,27 @@ export function shouldShowApplication(application: ILinuxApplication): boolean { ); } -export async function getAppIcon(name?: string) { - if (!name || path.isAbsolute(name)) { - return name; +export async function getImageDataUrl(imagePath: string): Promise<string> { + if (imagePath && path.extname(imagePath) === '.svg') { + const contents = await fs.promises.readFile(imagePath); + return `data:image/svg+xml;base64,${contents.toString('base64')}`; + } else { + const image = nativeImage.createFromPath(imagePath); + + if (image.isEmpty()) { + log.error(`Failed to load nativeImage: ${imagePath}`); + throw new Error(`Failed to load nativeImage: ${imagePath}`); + } else { + return image.toDataURL(); + } } +} +// Returns the path of the icon with the specified name. If none is found it returns undefined. +export async function findIconPath(name: string): Promise<string | undefined> { // Chromium doesn't support .xpm files const extensions = ['svg', 'png']; - const iconPath = await findIcon(name, extensions, [ + return findIcon(name, extensions, [ getIconDirectories(), await getGtkThemeDirectories(), // Begin with preferred sized but if nothing matches other sizes should be considered as well. @@ -54,19 +67,6 @@ export async function getAppIcon(name?: string) { // Search in all categories of icons. [/.*/], ]); - - if (iconPath && path.extname(iconPath) === '.svg') { - try { - const contents = await fs.promises.readFile(iconPath); - return `data:image/svg+xml;base64,${contents.toString('base64')}`; - } catch (error) { - log.error(`Failed to read icon of application: ${name},`, error); - } - } else if (iconPath) { - return nativeImage.createFromPath(iconPath).toDataURL(); - } - - return undefined; } // Implemented according to freedesktop specification. diff --git a/gui/src/main/linux-split-tunneling.ts b/gui/src/main/linux-split-tunneling.ts index 0552a41ff9..8103fc4d0e 100644 --- a/gui/src/main/linux-split-tunneling.ts +++ b/gui/src/main/linux-split-tunneling.ts @@ -4,7 +4,7 @@ import linuxAppList, { AppData } from 'linux-app-list'; import path from 'path'; import { pascalCaseToCamelCase } from './transform-object-keys'; import { ILinuxSplitTunnelingApplication } from '../shared/application-types'; -import { getAppIcon, shouldShowApplication } from './linux-desktop-entry'; +import { findIconPath, getImageDataUrl, shouldShowApplication } from './linux-desktop-entry'; const PROBLEMATIC_APPLICATIONS = { launchingInExistingProcess: [ @@ -42,11 +42,31 @@ export function getApplications(locale: string): Promise<ILinuxSplitTunnelingApp .filter(shouldShowApplication) .map(addApplicationWarnings) .sort((a, b) => a.name.localeCompare(b.name)) - .map(async (app) => ({ ...app, icon: await getAppIcon(app.icon) })); + .map(replaceIconNameWithDataUrl); return Promise.all(applications); } +async function replaceIconNameWithDataUrl( + app: ILinuxSplitTunnelingApplication, +): Promise<ILinuxSplitTunnelingApplication> { + try { + // Either the app has no icon or it's already an absolute path. + if (app.icon === undefined || path.isAbsolute(app.icon)) { + return app; + } + + const iconPath = await findIconPath(app.icon); + if (iconPath === undefined) { + return app; + } + + return { ...app, icon: await getImageDataUrl(iconPath) }; + } catch (e) { + return app; + } +} + function addApplicationWarnings( application: ILinuxSplitTunnelingApplication, ): ILinuxSplitTunnelingApplication { |
