diff --git a/build/icons/128x128.png b/build/icons/128x128.png index 4fbb9a35..5f392ce4 100644 Binary files a/build/icons/128x128.png and b/build/icons/128x128.png differ diff --git a/build/icons/16x16.png b/build/icons/16x16.png index dcb2ba50..f4092c34 100644 Binary files a/build/icons/16x16.png and b/build/icons/16x16.png differ diff --git a/build/icons/256x256.png b/build/icons/256x256.png index f670daba..d0a8448a 100644 Binary files a/build/icons/256x256.png and b/build/icons/256x256.png differ diff --git a/build/icons/32x32.png b/build/icons/32x32.png index 27607837..656bfcd3 100644 Binary files a/build/icons/32x32.png and b/build/icons/32x32.png differ diff --git a/build/icons/48x48.png b/build/icons/48x48.png index 18542816..235d695f 100644 Binary files a/build/icons/48x48.png and b/build/icons/48x48.png differ diff --git a/build/icons/512x512.png b/build/icons/512x512.png index 26afcdab..f513d4c9 100644 Binary files a/build/icons/512x512.png and b/build/icons/512x512.png differ diff --git a/build/icons/64x64.png b/build/icons/64x64.png index 0b3ab0db..cee6f4e6 100644 Binary files a/build/icons/64x64.png and b/build/icons/64x64.png differ diff --git a/electron-builder.config.cjs b/electron-builder.config.cjs index e85b6ff0..21e59516 100644 --- a/electron-builder.config.cjs +++ b/electron-builder.config.cjs @@ -147,10 +147,13 @@ module.exports = { shortcutName: 'Netcatty' }, linux: { - // Linux desktop icons render full-bleed like Windows — use the - // tight-crop source so the app icon doesn't look padded in KDE / - // GNOME launchers or AppImage integrations. - icon: 'public/icon-win.png', + // Linux .deb/.rpm/AppImage icons come from build/icons/* (see + // scripts/generate-linux-icons.sh). Point at the icons directory + // under buildResources — electron-builder still falls back to the + // 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'], category: 'Development', extraResources: [...moshExtraResources('linux'), ...etExtraResources('linux')] diff --git a/scripts/electron-builder-config.test.cjs b/scripts/electron-builder-config.test.cjs index f1e3e15e..4614c273 100644 --- a/scripts/electron-builder-config.test.cjs +++ b/scripts/electron-builder-config.test.cjs @@ -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. 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(", ")}`, + ); +}); diff --git a/scripts/generate-linux-icons.sh b/scripts/generate-linux-icons.sh new file mode 100755 index 00000000..08bd72f2 --- /dev/null +++ b/scripts/generate-linux-icons.sh @@ -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//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