diff --git a/src/platformPackager.ts b/src/platformPackager.ts index 3275bf9b2e1..4e33a001855 100644 --- a/src/platformPackager.ts +++ b/src/platformPackager.ts @@ -384,7 +384,7 @@ export abstract class PlatformPackager return `${deployment ? this.appInfo.name : this.appInfo.productFilename}-${this.appInfo.version}${classifier == null ? "" : `-${classifier}`}${dotExt}` } - protected async getDefaultIcon(ext: string) { + async getDefaultIcon(ext: string) { const resourceList = await this.resourceList const name = `icon.${ext}` if (resourceList.includes(name)) { diff --git a/src/targets/LinuxTargetHelper.ts b/src/targets/LinuxTargetHelper.ts index 7d1fdd62899..63a0935ef7a 100644 --- a/src/targets/LinuxTargetHelper.ts +++ b/src/targets/LinuxTargetHelper.ts @@ -30,38 +30,49 @@ export class LinuxTargetHelper { // must be name without spaces and other special characters, but not product name used private async computeDesktopIcons(): Promise>> { - const tempDir = await this.tempDirPromise - try { - const mappings: Array> = [] - const pngIconsDir = path.join(this.packager.buildResourcesDir, "icons") - let maxSize = 0 - for (let file of (await readdir(pngIconsDir))) { - if (file.endsWith(".png") || file.endsWith(".PNG")) { - // If parseInt encounters a character that is not a numeral in the specified radix, - // it returns the integer value parsed up to that point - try { - const size = parseInt(file!, 10) - if (size > 0) { - const iconPath = `${pngIconsDir}/${file}` - mappings.push([iconPath, `${size}x${size}/apps/${this.packager.appInfo.name}.png`]) - - if (size > maxSize) { - maxSize = size - this.maxIconPath = iconPath - } + const resourceList = await this.packager.resourceList + if (resourceList.includes("icons")) { + return this.iconsFromDir(path.join(this.packager.buildResourcesDir, "icons")) + } + else { + return this.createFromIcns(await this.tempDirPromise) + } + } + + private async iconsFromDir(iconsDir: string) { + const mappings: Array> = [] + let maxSize = 0 + for (let file of (await readdir(iconsDir))) { + if (file.endsWith(".png") || file.endsWith(".PNG")) { + // If parseInt encounters a character that is not a numeral in the specified radix, + // it returns the integer value parsed up to that point + try { + const size = parseInt(file!, 10) + if (size > 0) { + const iconPath = `${iconsDir}/${file}` + mappings.push([iconPath, `${size}x${size}/apps/${this.packager.appInfo.name}.png`]) + + if (size > maxSize) { + maxSize = size + this.maxIconPath = iconPath } } - catch (e) { - console.error(e) - } + } + catch (e) { + console.error(e) } } - - return mappings } - catch (e) { - return this.createFromIcns(tempDir) + return mappings + } + + private async getIcns(): Promise { + const build = this.packager.devMetadata.build + let iconPath = (build.mac || {}).icon || build.icon + if (iconPath != null && !iconPath.endsWith(".icns")) { + iconPath += ".icns" } + return iconPath == null ? await this.packager.getDefaultIcon("icns") : path.resolve(this.packager.projectDir, iconPath) } async computeDesktopEntry(exec?: string, extra?: string): Promise { @@ -86,7 +97,12 @@ ${extra == null ? "" : `${extra}\n`}`) } private async createFromIcns(tempDir: string): Promise>> { - const output = await exec("icns2png", ["-x", "-o", tempDir, path.join(this.packager.buildResourcesDir, "icon.icns")]) + const iconPath = await this.getIcns() + if (iconPath == null) { + return this.iconsFromDir(path.join(__dirname, "..", "..", "templates", "linux", "electron-icons")) + } + + const output = await exec("icns2png", ["-x", "-o", tempDir, iconPath]) debug(output) //noinspection UnnecessaryLocalVariableJS diff --git a/src/targets/appImage.ts b/src/targets/appImage.ts index ebec0706c38..f7703c670e8 100644 --- a/src/targets/appImage.ts +++ b/src/targets/appImage.ts @@ -28,7 +28,8 @@ export default class AppImageTarget extends TargetEx { async build(appOutDir: string, arch: Arch): Promise { const packager = this.packager - const image = path.join(this.outDir, packager.generateName("AppImage", arch, false)) + // avoid spaces in the file name + const image = path.join(this.outDir, packager.generateName("AppImage", arch, true)) const appInfo = packager.appInfo await unlinkIfExists(image) diff --git a/templates/linux/AppRun.sh b/templates/linux/AppRun.sh index cd2e7dd5bbe..19300f2f0ea 100755 --- a/templates/linux/AppRun.sh +++ b/templates/linux/AppRun.sh @@ -178,13 +178,28 @@ if [ -z "$SKIP" ] ; then RESOURCE_NAME=$(echo "$VENDORPREFIX-$DESKTOP_FILE_NAME" | sed -e 's/.desktop//g') echo "${RESOURCE_NAME}" - # Install the icon files for the application; TODO: scalable + # uninstall previous icons + xdg-icon-resource uninstall --noupdate --size 16 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 24 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 32 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 48 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 64 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 72 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 96 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 128 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 256 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 512 "$RESOURCE_NAME" + xdg-icon-resource uninstall --noupdate --size 1024 "$RESOURCE_NAME" + + # Install the icon files for the application ICONS=$(find "$APPDIR/usr/share/icons/" -path "*/apps/$APP.png" || true) for ICON in $ICONS ; do ICON_SIZE=$(echo "$ICON" | rev | cut -d "/" -f 3 | rev | cut -d "x" -f 1) - xdg-icon-resource install --context apps --size "$ICON_SIZE" "$ICON" "$RESOURCE_NAME" + xdg-icon-resource install --noupdate --context apps --size "$ICON_SIZE" "$ICON" "$RESOURCE_NAME" done + xdg-icon-resource forceupdate + # Install mime type find "$APPDIR/usr/share/mime/" -type f -name "*xml" -exec xdg-mime install ${SYSTEM_WIDE} --novendor {} \; || true diff --git a/templates/linux/electron-icons/128x128.png b/templates/linux/electron-icons/128x128.png new file mode 100755 index 00000000000..9bcc07d857d --- /dev/null +++ b/templates/linux/electron-icons/128x128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a16b3d28d0fb3258c1a88f202c49d5f1a9955741929c9b52b054796c4ba422dd +size 18107 diff --git a/templates/linux/electron-icons/16x16.png b/templates/linux/electron-icons/16x16.png new file mode 100755 index 00000000000..eee9260a26b --- /dev/null +++ b/templates/linux/electron-icons/16x16.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a01d5b26902cdee8ba0b55f106f34da1e9e3a97ecd741c98d6cbd67bed36713d +size 832 diff --git a/templates/linux/electron-icons/24x24.png b/templates/linux/electron-icons/24x24.png new file mode 100755 index 00000000000..01edf9eac1b --- /dev/null +++ b/templates/linux/electron-icons/24x24.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c98c7d2ebe12e69eb10dc9cf0a6d21ec131da88f0ef49bda8a2074c29c1d616e +size 1663 diff --git a/templates/linux/electron-icons/256x256.png b/templates/linux/electron-icons/256x256.png new file mode 100755 index 00000000000..ad0ecd496f4 --- /dev/null +++ b/templates/linux/electron-icons/256x256.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21e8e6c276c1544b8ff1e298d188addd129560879e6600809d904ce06d28bc59 +size 37977 diff --git a/templates/linux/electron-icons/32x32.png b/templates/linux/electron-icons/32x32.png new file mode 100755 index 00000000000..4369d9b31a9 --- /dev/null +++ b/templates/linux/electron-icons/32x32.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e901e0edf1ba6e4c17e16d61468515e9596066bd6a59fcc08dbb8e4d912d843 +size 2021 diff --git a/templates/linux/electron-icons/48x48.png b/templates/linux/electron-icons/48x48.png new file mode 100755 index 00000000000..d147904ccf6 --- /dev/null +++ b/templates/linux/electron-icons/48x48.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7f8bddb00beab51848da032e3602fef8ed247bbd3ceda9e733d3726418bbb02 +size 4476 diff --git a/templates/linux/electron-icons/64x64.png b/templates/linux/electron-icons/64x64.png new file mode 100755 index 00000000000..1c119fd67ad --- /dev/null +++ b/templates/linux/electron-icons/64x64.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91e4fcae9bbe818f08f4bbe4505114c5d7053c98e392e61452d7e4dc73e32790 +size 6621 diff --git a/templates/linux/electron-icons/96x96.png b/templates/linux/electron-icons/96x96.png new file mode 100755 index 00000000000..f2247f09e29 --- /dev/null +++ b/templates/linux/electron-icons/96x96.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca6228366551ac7ec493fb1f2c26dbc4afe8df429c6edb41e540a95fcffa3f9f +size 11888 diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index 7ee41bc9061..ed783612eb2 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -135,7 +135,7 @@ async function checkLinuxResult(projectDir: string, packager: Packager, checkOpt const result: Array = [] for (let target of nameToTarget.keys()) { if (target === "appimage") { - result.push(`${appInfo.productFilename}-${appInfo.version}-${arch === Arch.x64 ? "x86_64" : Arch[arch]}.AppImage`) + result.push(`${appInfo.name}-${appInfo.version}-${arch === Arch.x64 ? "x86_64" : Arch[arch]}.AppImage`) } else { result.push(`TestApp-${appInfo.version}.${target}`) diff --git a/test/src/linuxPackagerTest.ts b/test/src/linuxPackagerTest.ts index d2ada8c626c..adf3f69d0bd 100755 --- a/test/src/linuxPackagerTest.ts +++ b/test/src/linuxPackagerTest.ts @@ -14,6 +14,13 @@ test.ifDevOrLinuxCi("AppImage", () => assertPack("test-app-one", { } )) +test.ifDevOrLinuxCi("AppImage - default icon", () => assertPack("test-app-one", { + targets: Platform.LINUX.createTarget("appimage"), + }, { + tempDirCreated: projectDir => remove(path.join(projectDir, "build")) + }, +)) + // "apk" is very slow, don't test for now test.ifDevOrLinuxCi("targets", () => assertPack("test-app-one", { targets: Platform.LINUX.createTarget(["sh", "freebsd", "pacman", "zip", "7z"]),