fix(nix): restore desktop app icon matching (#2506)
* fix(nix): identify desktop app for icon matching * fix(desktop): ignore wrapper class in CLI passthrough * fix(nix): give the Electron launcher a real app root The Wayland app_id — what a bar or taskbar uses to find the .desktop entry, and therefore the icon — is fixed during Electron startup, so neither `--class=` nor main.ts's `app.setName()` reaches it on current Electron. Launching `electron path/to/main.js` gives Electron no package.json to read a name from, so the window published the default "electron" app_id and shells drew the generic Electron icon. Launch a one-file app root named "paseo-desktop" instead, matching the installed desktop entry and hicolor icon. Older Electron (38) derives the app_id from the runtime app name "Paseo", so also ship a NoDisplay alias entry under that name; the icon resolves either way and the launcher list still shows a single Paseo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fdb39d2111
commit
5d15e40a2b
+29
-2
@@ -187,11 +187,22 @@ buildNpmPackage {
|
||||
install -Dm644 packages/desktop/assets/icon.png \
|
||||
$out/share/icons/hicolor/512x512/apps/paseo-desktop.png
|
||||
|
||||
# Electron derives Wayland's toplevel app_id from the package name in the
|
||||
# app root it launches. Point it at a one-file app named "paseo-desktop"
|
||||
# so shells can match the window to the desktop entry and hicolor icon.
|
||||
mkdir -p $out/share/paseo-desktop/electron-app
|
||||
printf '%s\n' "{ \"name\": \"paseo-desktop\", \"version\": \"$version\", \"main\": \"index.js\" }" \
|
||||
> $out/share/paseo-desktop/electron-app/package.json
|
||||
printf '%s\n' 'require("../packages/desktop/dist/main.js");' \
|
||||
> $out/share/paseo-desktop/electron-app/index.js
|
||||
|
||||
# Chromium's setuid sandbox cannot live in the immutable Nix store.
|
||||
makeWrapper ${electron}/bin/electron $out/bin/paseo-desktop \
|
||||
--add-flags "$out/share/paseo-desktop/packages/desktop/dist/main.js" \
|
||||
--add-flags "$out/share/paseo-desktop/electron-app" \
|
||||
--add-flags "--no-sandbox" \
|
||||
--set EXPO_DEV_URL "paseo://app/"
|
||||
--add-flags "--class=paseo-desktop" \
|
||||
--set EXPO_DEV_URL "paseo://app/" \
|
||||
--set CHROME_DESKTOP "paseo-desktop.desktop"
|
||||
|
||||
copyDesktopItems
|
||||
''}
|
||||
@@ -219,7 +230,23 @@ buildNpmPackage {
|
||||
exec = "paseo-desktop";
|
||||
icon = "paseo-desktop";
|
||||
categories = ["Development"];
|
||||
startupWMClass = "paseo-desktop";
|
||||
})
|
||||
# Hidden alias entry. Which of the two names Electron ends up publishing as
|
||||
# the Wayland app_id depends on the Electron version: 41 uses the app-root
|
||||
# package.json `name` ("paseo-desktop"), 38 uses the runtime app name that
|
||||
# main.ts sets ("Paseo"). Ship a NoDisplay entry for the second spelling so
|
||||
# the icon resolves either way without a duplicate launcher item.
|
||||
(makeDesktopItem {
|
||||
name = "Paseo";
|
||||
desktopName = "Paseo";
|
||||
genericName = "AI Coding Agents";
|
||||
comment = "Self-hosted daemon for AI coding agents";
|
||||
exec = "paseo-desktop";
|
||||
icon = "paseo-desktop";
|
||||
categories = [ "Development" ];
|
||||
startupWMClass = "Paseo";
|
||||
noDisplay = true;
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
@@ -65,6 +65,23 @@ describe("passthrough CLI", () => {
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("ignores Linux desktop identity arguments injected by the Nix wrapper", () => {
|
||||
expect(
|
||||
parsePassthroughCliArgs({
|
||||
argv: [
|
||||
"/nix/store/electron/bin/electron",
|
||||
"/nix/store/paseo-desktop/share/paseo-desktop/electron-app",
|
||||
"--no-sandbox",
|
||||
"--class=paseo-desktop",
|
||||
"daemon",
|
||||
"status",
|
||||
],
|
||||
isDefaultApp: true,
|
||||
forceCli: false,
|
||||
}),
|
||||
).toEqual(["daemon", "status"]);
|
||||
});
|
||||
|
||||
it("ignores Electron remote debugging switches", () => {
|
||||
expect(
|
||||
parsePassthroughCliArgs({
|
||||
|
||||
@@ -2,7 +2,7 @@ import { pathToFileURL } from "node:url";
|
||||
import { resolvePassthroughCliEntrypoint } from "./entrypoints.js";
|
||||
|
||||
const DESKTOP_CLI_ENV = "PASEO_DESKTOP_CLI";
|
||||
const IGNORED_ARG_PREFIXES = ["-psn_", "--no-sandbox", "--remote-debugging-port="];
|
||||
const IGNORED_ARG_PREFIXES = ["-psn_", "--class=", "--no-sandbox", "--remote-debugging-port="];
|
||||
|
||||
export type PassthroughCliRunner = (argv: string[]) => Promise<number>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user