From 1535b8802eb89c2f57817504b5fcc026ad1d5b97 Mon Sep 17 00:00:00 2001 From: Kevin Boos Date: Fri, 28 Jun 2024 17:33:45 -0700 Subject: [PATCH 1/4] feat(debian): auto-add an Exec arg (field code) in the `.desktop` file This change adds an `{exec_arg}` field to the default `main.desktop` template. This field is populated by handlebars with a sane default value, which is based on whether `deep_link_protocols` or `file_associations` in the `Config` struct have been specified. This allows an installed Debian package to be invoked by other applications with URLs or files as arguments, as expected. The `main.desktop` template previously did not automatically include an Exec field code even if `deep_link_protocols` or `file_associations` were set, which would confuse new users who incorrectly expected that the Debian package would automatically handle links and file associations upon installation. This change now ensures their expectations are met. --- crates/packager/src/config/mod.rs | 19 +++++++++++++++++-- crates/packager/src/package/deb/main.desktop | 2 +- crates/packager/src/package/deb/mod.rs | 18 ++++++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/crates/packager/src/config/mod.rs b/crates/packager/src/config/mod.rs index 1a022b2c..505247a4 100644 --- a/crates/packager/src/config/mod.rs +++ b/crates/packager/src/config/mod.rs @@ -194,7 +194,7 @@ pub struct DebianConfig { /// {{#if comment}} /// Comment={{comment}} /// {{/if}} - /// Exec={{exec}} + /// Exec={{exec}} {{exec_arg}} /// Icon={{icon}} /// Name={{name}} /// Terminal=false @@ -203,6 +203,21 @@ pub struct DebianConfig { /// MimeType={{mime_type}} /// {{/if}} /// ``` + /// + /// The `exec_arg` will be set to: + /// * "%U", if at least one [Config::deep_link_protocols] was specified. + /// * This means that your application can accommodate being invoked with multiple URLs. + /// * "%F", if at least one [Config::file_associations] was specified but no deep link protocols were given, or + /// * This means that your application can accommodate being invoked with multiple file paths. + /// * An empty string "" (nothing) otherwise. + /// * This means that your application will never be invoked with any URLs or file paths. + /// + /// To specify a custom `exec_arg`, just use plaintext directly instead of `{{exec_arg}}`: + /// ```text + /// Exec={{exec}} %u + /// ``` + /// + /// See more here: . #[serde(alias = "desktop-template", alias = "desktop_template")] pub desktop_template: Option, /// Define the section in Debian Control file. See : @@ -243,7 +258,7 @@ impl DebianConfig { /// {{#if comment}} /// Comment={{comment}} /// {{/if}} - /// Exec={{exec}} + /// Exec={{exec}} {{exec_arg}} /// Icon={{icon}} /// Name={{name}} /// Terminal=false diff --git a/crates/packager/src/package/deb/main.desktop b/crates/packager/src/package/deb/main.desktop index 721648d0..a5f72023 100644 --- a/crates/packager/src/package/deb/main.desktop +++ b/crates/packager/src/package/deb/main.desktop @@ -3,7 +3,7 @@ Categories={{categories}} {{#if comment}} Comment={{comment}} {{/if}} -Exec={{exec}} +Exec={{exec}} {{exec_arg}} Icon={{icon}} Name={{name}} Terminal=false diff --git a/crates/packager/src/package/deb/mod.rs b/crates/packager/src/package/deb/mod.rs index 8390cf43..3c3f29f6 100644 --- a/crates/packager/src/package/deb/mod.rs +++ b/crates/packager/src/package/deb/mod.rs @@ -96,8 +96,8 @@ fn generate_desktop_file(config: &Config, data_dir: &Path) -> crate::Result<()> .join("usr/share/applications") .join(desktop_file_name); - // For more information about the format of this file, see - // https://developer.gnome.org/integration-guide/stable/desktop-files.html.en + // For more information about the format of this file, see: + // let file = &mut util::create_file(&desktop_file_path)?; let mut handlebars = Handlebars::new(); @@ -117,14 +117,22 @@ fn generate_desktop_file(config: &Config, data_dir: &Path) -> crate::Result<()> categories: &'a str, comment: Option<&'a str>, exec: &'a str, + exec_arg: Option<&'a str>, icon: &'a str, name: &'a str, mime_type: Option, } + // Set the argument code at the end of the `Exec` key. + // See the docs for `DebianConfig::desktop_template` for more details. + let mut exec_arg = None; + let mut mime_type: Vec = Vec::new(); if let Some(associations) = &config.file_associations { + if !associations.is_empty() { + exec_arg = Some("%F"); + } mime_type.extend( associations .iter() @@ -133,6 +141,11 @@ fn generate_desktop_file(config: &Config, data_dir: &Path) -> crate::Result<()> } if let Some(protocols) = &config.deep_link_protocols { + if !protocols.is_empty() { + // Use "%U" even if file associations were already provided, + // as it can also accommodate file names in addition to URLs. + exec_arg = Some("%U"); + } mime_type.extend( protocols .iter() @@ -152,6 +165,7 @@ fn generate_desktop_file(config: &Config, data_dir: &Path) -> crate::Result<()> .unwrap_or(""), comment: config.description.as_deref(), exec: &bin_name, + exec_arg, icon: &bin_name, name: config.product_name.as_str(), mime_type, From b6a3b1c1cb9b5fc7da6ab2703eb37ddf052e20aa Mon Sep 17 00:00:00 2001 From: Kevin Boos Date: Fri, 28 Jun 2024 17:42:33 -0700 Subject: [PATCH 2/4] Add change file --- .changes/pr256.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .changes/pr256.md diff --git a/.changes/pr256.md b/.changes/pr256.md new file mode 100644 index 00000000..d236459b --- /dev/null +++ b/.changes/pr256.md @@ -0,0 +1,13 @@ +--- +"cargo-packager": "patch" +"@crabnebula/packager": "patch" +--- + +Automatically add an Exec arg (field code) in the `.desktop` file. + +This adds an `{exec_arg}` field to the default `main.desktop` template. +This field is populated with a sane default value, based on the +`deep_link_protocols` or `file_associations` in the `Config` struct. + +This allows an installed Debian package to be invoked by other +applications with URLs or files as arguments, as expected. From 361cd0f9de950efd0836a3fca81b52b987030148 Mon Sep 17 00:00:00 2001 From: Kevin Boos <1139460+kevinaboos@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:11:48 -0700 Subject: [PATCH 3/4] Update crates/packager/src/config/mod.rs Co-authored-by: Amr Bashir --- crates/packager/src/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/packager/src/config/mod.rs b/crates/packager/src/config/mod.rs index 505247a4..cc778b46 100644 --- a/crates/packager/src/config/mod.rs +++ b/crates/packager/src/config/mod.rs @@ -204,7 +204,7 @@ pub struct DebianConfig { /// {{/if}} /// ``` /// - /// The `exec_arg` will be set to: + /// The `{{exec_arg}}` will be set to: /// * "%U", if at least one [Config::deep_link_protocols] was specified. /// * This means that your application can accommodate being invoked with multiple URLs. /// * "%F", if at least one [Config::file_associations] was specified but no deep link protocols were given, or From 6c2e91b9f9ac277ca851def4cf1f84016ff28048 Mon Sep 17 00:00:00 2001 From: Kevin Boos Date: Mon, 1 Jul 2024 17:18:25 -0700 Subject: [PATCH 4/4] improve doc comment about `exec_arg` for `DebianConfig::desktop_template` --- bindings/packager/nodejs/schema.json | 2 +- crates/packager/schema.json | 2 +- crates/packager/src/config/mod.rs | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/bindings/packager/nodejs/schema.json b/bindings/packager/nodejs/schema.json index a7692a50..ee823dfe 100644 --- a/bindings/packager/nodejs/schema.json +++ b/bindings/packager/nodejs/schema.json @@ -785,7 +785,7 @@ } }, "desktopTemplate": { - "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.\n\nDefault file contents: ```text [Desktop Entry] Categories={{categories}} {{#if comment}} Comment={{comment}} {{/if}} Exec={{exec}} Icon={{icon}} Name={{name}} Terminal=false Type=Application {{#if mime_type}} MimeType={{mime_type}} {{/if}} ```", + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.\n\nDefault file contents: ```text [Desktop Entry] Categories={{categories}} {{#if comment}} Comment={{comment}} {{/if}} Exec={{exec}} {{exec_arg}} Icon={{icon}} Name={{name}} Terminal=false Type=Application {{#if mime_type}} MimeType={{mime_type}} {{/if}} ```\n\nThe `{{exec_arg}}` will be set to: * \"%F\", if at least one [Config::file_associations] was specified but no deep link protocols were given. * The \"%F\" arg means that your application can be invoked with multiple file paths. * \"%U\", if at least one [Config::deep_link_protocols] was specified. * The \"%U\" arg means that your application can be invoked with multiple URLs. * If both [Config::file_associations] and [Config::deep_link_protocols] were specified, the \"%U\" arg will be used, causing the file paths to be passed to your app as `file://` URLs. * An empty string \"\" (nothing) if neither are given. * This means that your application will never be invoked with any URLs or file paths.\n\nTo specify a custom `exec_arg`, just use plaintext directly instead of `{{exec_arg}}`: ```text Exec={{exec}} %u ```\n\nSee more here: .", "type": [ "string", "null" diff --git a/crates/packager/schema.json b/crates/packager/schema.json index a7692a50..ee823dfe 100644 --- a/crates/packager/schema.json +++ b/crates/packager/schema.json @@ -785,7 +785,7 @@ } }, "desktopTemplate": { - "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.\n\nDefault file contents: ```text [Desktop Entry] Categories={{categories}} {{#if comment}} Comment={{comment}} {{/if}} Exec={{exec}} Icon={{icon}} Name={{name}} Terminal=false Type=Application {{#if mime_type}} MimeType={{mime_type}} {{/if}} ```", + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.\n\nDefault file contents: ```text [Desktop Entry] Categories={{categories}} {{#if comment}} Comment={{comment}} {{/if}} Exec={{exec}} {{exec_arg}} Icon={{icon}} Name={{name}} Terminal=false Type=Application {{#if mime_type}} MimeType={{mime_type}} {{/if}} ```\n\nThe `{{exec_arg}}` will be set to: * \"%F\", if at least one [Config::file_associations] was specified but no deep link protocols were given. * The \"%F\" arg means that your application can be invoked with multiple file paths. * \"%U\", if at least one [Config::deep_link_protocols] was specified. * The \"%U\" arg means that your application can be invoked with multiple URLs. * If both [Config::file_associations] and [Config::deep_link_protocols] were specified, the \"%U\" arg will be used, causing the file paths to be passed to your app as `file://` URLs. * An empty string \"\" (nothing) if neither are given. * This means that your application will never be invoked with any URLs or file paths.\n\nTo specify a custom `exec_arg`, just use plaintext directly instead of `{{exec_arg}}`: ```text Exec={{exec}} %u ```\n\nSee more here: .", "type": [ "string", "null" diff --git a/crates/packager/src/config/mod.rs b/crates/packager/src/config/mod.rs index cc778b46..65b44a8e 100644 --- a/crates/packager/src/config/mod.rs +++ b/crates/packager/src/config/mod.rs @@ -205,11 +205,13 @@ pub struct DebianConfig { /// ``` /// /// The `{{exec_arg}}` will be set to: + /// * "%F", if at least one [Config::file_associations] was specified but no deep link protocols were given. + /// * The "%F" arg means that your application can be invoked with multiple file paths. /// * "%U", if at least one [Config::deep_link_protocols] was specified. - /// * This means that your application can accommodate being invoked with multiple URLs. - /// * "%F", if at least one [Config::file_associations] was specified but no deep link protocols were given, or - /// * This means that your application can accommodate being invoked with multiple file paths. - /// * An empty string "" (nothing) otherwise. + /// * The "%U" arg means that your application can be invoked with multiple URLs. + /// * If both [Config::file_associations] and [Config::deep_link_protocols] were specified, + /// the "%U" arg will be used, causing the file paths to be passed to your app as `file://` URLs. + /// * An empty string "" (nothing) if neither are given. /// * This means that your application will never be invoked with any URLs or file paths. /// /// To specify a custom `exec_arg`, just use plaintext directly instead of `{{exec_arg}}`: