electron-userland / electron-builder

A complete solution to package and build a ready for distribution Electron app with “auto update” support out of the box
https://www.electron.build
MIT License
13.7k stars 1.74k forks source link

Desktop Launcher Actions to .desktop file #8556

Closed rmartins90 closed 1 month ago

rmartins90 commented 1 month ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch app-builder-lib@24.13.3 for the project I'm working on.

As far as I could tell, electron-builder does not support specifying desktop action entries in .desktop file (https://www.electronjs.org/docs/latest/tutorial/linux-desktop-actions). So I patched the LinuxTargetHelpers.js file to support it quickly:

diff --git a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
index c3f1000..bda9496 100644
--- a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
+++ b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
@@ -155,11 +155,26 @@ class LinuxTargetHelper {
             }
         }
         desktopMeta.Categories = `${category}${category.endsWith(";") ? "" : ";"}`;
+
         let data = `[Desktop Entry]`;
         for (const name of Object.keys(desktopMeta)) {
-            data += `\n${name}=${desktopMeta[name]}`;
+            if (name != "DesktopActions") {
+                data += `\n${name}=${desktopMeta[name]}`;
+            }
         }
         data += "\n";
+
+        // Specify Desktop Actions
+        if (desktopMeta.DesktopActions) {
+            for (const actionName of Object.keys(desktopMeta.DesktopActions)) {
+                const action = desktopMeta.DesktopActions[actionName];
+                data += `\n[Desktop Action ${actionName}]`;
+                for (const name of Object.keys(action)) {
+                    data += `\n${name}=${action[name]}`;
+                }
+                data += "\n";
+            }
+        }
         return Promise.resolve(data);
     }
 }

For a config file like the following:

DesktopActions: {
                NewWindow: {
                    Name: 'New Window',
                    Exec: 'app --new-window',
                },
            },

Are there any plans to support this soon, or should I propose a more robust solution?

This issue body was partially generated by patch-package.

mmaietta commented 1 month ago

This is great! Quick Q, are there other things in the .desktop file that should be supported apart from [Desktop Entry]? I'd rather make something extensible instead of adding another specific DesktopActions configuration property. One option is could be as simple as providing a path to your own .desktop file that electron-builder adds default entries to (as-needed).

rmartins90 commented 1 month ago

are there other things in the .desktop file that should be supported apart from [Desktop Entry]?

A quick looking for spec seems that [Desktop Entry] and [Desktop Action] are the only entries available https://specifications.freedesktop.org/desktop-entry-spec/latest/

One option is could be as simple as providing a path to your own .desktop file that electron-builder adds default entries to (as-needed).

Agree that this is the most straightforward approach.

mmaietta commented 1 month ago

This may be an amateur question, but I'm quite unfamiliar with desktop files. Is the .desktop file limited to a specific distribution method? (eg. rpm, deb, pacman, snap, AppImage, flatpak, etc) I ask because I'm trying to figure out where to insert the new configuration property. There are LinuxConfiguration, CommonLinuxOptions, LinuxTargetSpecificOptions, DebOptions SnapOptions, and more (one for each distribution target)

rmartins90 commented 1 month ago

I am also not very familiar with desktop files, but they should be general-purpose and used across different packaging formats and desktop environments. I'm just not entirely sure that some distribution methods may not support it out of the box.

Both the KDE and GNOME desktop environments have adopted a similar format for "desktop entries", or configuration files describing how a particular program is to be launched, how it appears in menus, etc. It is to the larger community's benefit that a unified standard be agreed upon by all parties such that interoperation between the two environments, and indeed any additional environments that implement the specification, becomes simpler.

So, I think CommonLinuxOptions is probably the most appropriate for this.

mmaietta commented 1 month ago

One option is could be as simple as providing a path to your own .desktop file that electron-builder adds default entries to (as-needed).

So I've been playing around with this, and even though it's extensible, it also seems nigh impossible to parse a .desktop file and determine what to replace.

I'm thinking of a new approach that changes the format of desktop configuration property to be an object as opposed to any. This would be a breaking change, but we just entered v26-alpha, so a breaking change would be okay

export interface LinuxDesktopFile {
  /**
   * `[Desktop Entry]` metadata entries (name to value). Overwrites default values calculated by electron-builder
   */
  entry?: {
    [k: string]: string
  }
  /**
   * `[Desktop Actions <ActionName>]` metadata entries (name to value).
   *
   * Example:
   * NewWindow: {
   *    Name: 'New Window',
   *    Exec: 'app --new-window',
   * }
   */
  desktopActions?: {
    [ActionName: string]: any
  }
}
mmaietta commented 1 month ago

Quick update, this was released in v26.0.0-alpha.0. Please give it a shot when you have a chance!