fix(linux): Ubuntu software icon missing due to single-size linux.icon override (#1341)
* fix(linux): restore multi-size hicolor icons for Ubuntu launchers (#1340) PR #816 set linux.icon to a single 1024px PNG, which regressed the #274 fix and left only hicolor/1024x1024 on .deb installs. Drop the override so electron-builder uses build/icons again, regenerate those PNGs from the tight-crop icon-win source, and add a helper script plus a config test. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(linux): set linux.icon to icons dir for proper multi-size hicolor icons (#1340) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 645 B After Width: | Height: | Size: 696 B |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -147,10 +147,13 @@ module.exports = {
|
|||||||
shortcutName: 'Netcatty'
|
shortcutName: 'Netcatty'
|
||||||
},
|
},
|
||||||
linux: {
|
linux: {
|
||||||
// Linux desktop icons render full-bleed like Windows — use the
|
// Linux .deb/.rpm/AppImage icons come from build/icons/* (see
|
||||||
// tight-crop source so the app icon doesn't look padded in KDE /
|
// scripts/generate-linux-icons.sh). Point at the icons directory
|
||||||
// GNOME launchers or AppImage integrations.
|
// under buildResources — electron-builder still falls back to the
|
||||||
icon: 'public/icon-win.png',
|
// top-level icon (public/icon.png) when linux.icon is unset, which
|
||||||
|
// installs only hicolor/1024x1024 and launchers miss the icon (#274,
|
||||||
|
// #1340). Do NOT set linux.icon to a single 1024px PNG either.
|
||||||
|
icon: 'icons',
|
||||||
target: ['AppImage', 'deb', 'rpm'],
|
target: ['AppImage', 'deb', 'rpm'],
|
||||||
category: 'Development',
|
category: 'Development',
|
||||||
extraResources: [...moshExtraResources('linux'), ...etExtraResources('linux')]
|
extraResources: [...moshExtraResources('linux'), ...etExtraResources('linux')]
|
||||||
|
|||||||
@@ -53,3 +53,37 @@ test("asarUnpack keeps MCP server runtime deps unpacked", () => {
|
|||||||
// @modelcontextprotocol/sdk is now a direct dep and the MCP server hard-requires it.
|
// @modelcontextprotocol/sdk is now a direct dep and the MCP server hard-requires it.
|
||||||
assert.ok(config.asarUnpack.includes("node_modules/@modelcontextprotocol/sdk/**/*"));
|
assert.ok(config.asarUnpack.includes("node_modules/@modelcontextprotocol/sdk/**/*"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("linux packaging uses multi-size build/icons instead of a single 1024px override", async () => {
|
||||||
|
assert.equal(
|
||||||
|
config.linux.icon,
|
||||||
|
"icons",
|
||||||
|
"linux.icon must point at build/icons so electron-builder installs hicolor/* sizes",
|
||||||
|
);
|
||||||
|
assert.equal(config.directories.buildResources, "build");
|
||||||
|
|
||||||
|
const fs = require("node:fs");
|
||||||
|
const path = require("node:path");
|
||||||
|
const iconsDir = path.join(__dirname, "..", "build", "icons");
|
||||||
|
for (const size of [16, 32, 48, 64, 128, 256, 512]) {
|
||||||
|
const file = path.join(iconsDir, `${size}x${size}.png`);
|
||||||
|
assert.ok(fs.existsSync(file), `expected Linux icon: build/icons/${size}x${size}.png`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { convertIcon } = require("app-builder-lib/out/util/iconConverter");
|
||||||
|
const projectDir = path.join(__dirname, "..");
|
||||||
|
const buildResources = path.join(projectDir, config.directories.buildResources);
|
||||||
|
const sources = [config.linux.icon, config.mac?.icon ?? config.icon].filter(Boolean);
|
||||||
|
const result = await convertIcon({
|
||||||
|
sources,
|
||||||
|
fallbackSources: [buildResources],
|
||||||
|
roots: [buildResources, projectDir],
|
||||||
|
format: "set",
|
||||||
|
outDir: path.join(projectDir, "release", ".icon-config-test"),
|
||||||
|
});
|
||||||
|
const sizes = result.icons.map((icon) => icon.size);
|
||||||
|
assert.ok(
|
||||||
|
sizes.includes(48) && sizes.includes(256) && !sizes.every((size) => size === 1024),
|
||||||
|
`expected standard hicolor sizes, got: ${sizes.join(", ")}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
31
scripts/generate-linux-icons.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Generate build/icons/* from public/icon-win.png for Linux packaging.
|
||||||
|
# electron-builder installs these into /usr/share/icons/hicolor/<size>/apps/.
|
||||||
|
#
|
||||||
|
# Requires ImageMagick (`convert`). Run from repo root:
|
||||||
|
# ./scripts/generate-linux-icons.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
SOURCE="$ROOT/public/icon-win.png"
|
||||||
|
OUT_DIR="$ROOT/build/icons"
|
||||||
|
|
||||||
|
if command -v magick >/dev/null 2>&1; then
|
||||||
|
CONVERT=(magick)
|
||||||
|
elif command -v convert >/dev/null 2>&1; then
|
||||||
|
CONVERT=(convert)
|
||||||
|
else
|
||||||
|
echo "error: ImageMagick is required (magick or convert)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$SOURCE" ]]; then
|
||||||
|
echo "error: source icon not found: $SOURCE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
for size in 16 32 48 64 128 256 512; do
|
||||||
|
"${CONVERT[@]}" "$SOURCE" -resize "${size}x${size}!" "$OUT_DIR/${size}x${size}.png"
|
||||||
|
echo "wrote build/icons/${size}x${size}.png"
|
||||||
|
done
|
||||||