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>
This commit is contained in:
陈大猫
2026-06-09 18:26:07 +08:00
committed by GitHub
parent d85f4edbbb
commit 437253179e
10 changed files with 72 additions and 4 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 B

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -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')]

View File

@@ -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
View 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