From 4741c5c61d6fb2817c9da33dafd7c58522b75f2f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:03:59 +0000 Subject: [PATCH 1/2] Initial plan From 6b8f2ca6a3229e7fdc352ea2791cd4c6132b50c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:13:03 +0000 Subject: [PATCH 2/2] feat: use desktopName from package.json for StartupWMClass in desktop entry When desktopName is set in package.json, use it (with .desktop extension stripped) as the StartupWMClass value in the generated desktop entry file. This ensures the WM_CLASS matches Electron's app_id, which is also derived from desktopName, allowing desktop environments to properly associate windows with their desktop entries. Falls back to productName when desktopName is not set. Fixes #7159 Co-authored-by: mmaietta <5238867+mmaietta@users.noreply.github.com> --- .../app-builder-lib/src/options/metadata.ts | 2 ++ .../src/targets/LinuxTargetHelper.ts | 13 ++++++++- .../snapshots/linux/linuxPackagerTest.js.snap | 29 +++++++++++++++++++ test/src/linux/linuxPackagerTest.ts | 28 ++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/packages/app-builder-lib/src/options/metadata.ts b/packages/app-builder-lib/src/options/metadata.ts index 223362255a7..94e3fb86969 100644 --- a/packages/app-builder-lib/src/options/metadata.ts +++ b/packages/app-builder-lib/src/options/metadata.ts @@ -50,6 +50,8 @@ export interface Metadata { readonly productName?: string | null /** @private */ readonly main?: string | null + /** @private */ + readonly desktopName?: string | null } export interface AuthorMetadata { diff --git a/packages/app-builder-lib/src/targets/LinuxTargetHelper.ts b/packages/app-builder-lib/src/targets/LinuxTargetHelper.ts index 14f24257c71..6b43cde445f 100644 --- a/packages/app-builder-lib/src/targets/LinuxTargetHelper.ts +++ b/packages/app-builder-lib/src/targets/LinuxTargetHelper.ts @@ -129,6 +129,17 @@ export class LinuxTargetHelper { } } + // https://github.com/electron-userland/electron-builder/issues/7159 + // Electron uses desktopName from package.json to set the app_id, which should match StartupWMClass. + // https://github.com/electron/electron/blob/9a7b73b5334f1d72c08e2d5e94106706ed751186/lib/browser/init.ts#L128-L133 + const desktopName = packager.info.metadata.desktopName + let wmClass: string + if (!isEmptyOrSpaces(desktopName)) { + wmClass = desktopName!.replace(/\.desktop$/, "") + } else { + wmClass = appInfo.productName + } + const desktopMeta: any = { Name: appInfo.productName, Exec: exec, @@ -140,7 +151,7 @@ export class LinuxTargetHelper { // to get WM_CLASS of running window: xprop WM_CLASS // StartupWMClass doesn't work for unicode // https://github.com/electron/electron/blob/2-0-x/atom/browser/native_window_views.cc#L226 - StartupWMClass: appInfo.productName, + StartupWMClass: wmClass, ...extra, ...(targetSpecificOptions.desktop?.entry ?? {}), } diff --git a/test/snapshots/linux/linuxPackagerTest.js.snap b/test/snapshots/linux/linuxPackagerTest.js.snap index 92d7a6413a1..d7403ad10f9 100644 --- a/test/snapshots/linux/linuxPackagerTest.js.snap +++ b/test/snapshots/linux/linuxPackagerTest.js.snap @@ -42,6 +42,35 @@ exports[`AppImage - default icon, custom executable and custom desktop 2`] = ` exports[`AppImage - deprecated systemIntegration 1`] = `"ERR_ELECTRON_BUILDER_INVALID_CONFIGURATION"`; +exports[`AppImage - desktopName sets StartupWMClass 1`] = ` +"[Desktop Entry] +Name=Signal +Exec=AppRun --no-sandbox %U +Terminal=false +Type=Application +Icon=testapp +StartupWMClass=signal +Comment=Test Application (test quite “ #378) +Categories=Development; +" +`; + +exports[`AppImage - desktopName sets StartupWMClass 2`] = ` +{ + "linux": [ + { + "arch": "x64", + "file": "Signal-1.1.0.AppImage", + "updateInfo": { + "blockMapSize": "@blockMapSize", + "sha512": "@sha512", + "size": "@size", + }, + }, + ], +} +`; + exports[`AppImage 1`] = ` { "linux": [ diff --git a/test/src/linux/linuxPackagerTest.ts b/test/src/linux/linuxPackagerTest.ts index b82cfbfdd32..2c105393928 100644 --- a/test/src/linux/linuxPackagerTest.ts +++ b/test/src/linux/linuxPackagerTest.ts @@ -319,6 +319,34 @@ test.ifNotWindows("no-author-email", ({ expect }) => ) ) +test.ifNotWindows("AppImage - desktopName sets StartupWMClass", ({ expect }) => + app( + expect, + { + targets: appImageTarget, + config: { + productName: "Signal", + }, + effectiveOptionComputed: async it => { + const content: string = it.desktop + expect( + content + .split("\n") + .filter(it => !it.includes("X-AppImage-BuildId") && !it.includes("X-AppImage-Version")) + .join("\n") + ).toMatchSnapshot() + return Promise.resolve(false) + }, + }, + { + projectDirCreated: projectDir => + modifyPackageJson(projectDir, data => { + data.desktopName = "signal.desktop" + }), + } + ) +) + test.ifNotWindows("forbid desktop.Exec", ({ expect }) => appThrows(expect, { targets: appImageTarget,