Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/app-builder-lib/src/options/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface Metadata {
readonly productName?: string | null
/** @private */
readonly main?: string | null
/** @private */
readonly desktopName?: string | null
}

export interface AuthorMetadata {
Expand Down
13 changes: 12 additions & 1 deletion packages/app-builder-lib/src/targets/LinuxTargetHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 ?? {}),
}
Expand Down
29 changes: 29 additions & 0 deletions test/snapshots/linux/linuxPackagerTest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
28 changes: 28 additions & 0 deletions test/src/linux/linuxPackagerTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down