Skip to content

Commit

Permalink
feat(debian): auto-add an Exec arg (field code) in the .desktop file (
Browse files Browse the repository at this point in the history
#256)

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.
  • Loading branch information
kevinaboos committed Jul 2, 2024
1 parent 6c7120f commit de4dcca
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 7 deletions.
13 changes: 13 additions & 0 deletions .changes/pr256.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion bindings/packager/nodejs/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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: <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables>.",
"type": [
"string",
"null"
Expand Down
2 changes: 1 addition & 1 deletion crates/packager/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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: <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables>.",
"type": [
"string",
"null"
Expand Down
21 changes: 19 additions & 2 deletions crates/packager/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ pub struct DebianConfig {
/// {{#if comment}}
/// Comment={{comment}}
/// {{/if}}
/// Exec={{exec}}
/// Exec={{exec}} {{exec_arg}}
/// Icon={{icon}}
/// Name={{name}}
/// Terminal=false
Expand All @@ -203,6 +203,23 @@ pub struct DebianConfig {
/// MimeType={{mime_type}}
/// {{/if}}
/// ```
///
/// 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.
/// * 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}}`:
/// ```text
/// Exec={{exec}} %u
/// ```
///
/// See more here: <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables>.
#[serde(alias = "desktop-template", alias = "desktop_template")]
pub desktop_template: Option<PathBuf>,
/// Define the section in Debian Control file. See : <https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections>
Expand Down Expand Up @@ -243,7 +260,7 @@ impl DebianConfig {
/// {{#if comment}}
/// Comment={{comment}}
/// {{/if}}
/// Exec={{exec}}
/// Exec={{exec}} {{exec_arg}}
/// Icon={{icon}}
/// Name={{name}}
/// Terminal=false
Expand Down
2 changes: 1 addition & 1 deletion crates/packager/src/package/deb/main.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Categories={{categories}}
{{#if comment}}
Comment={{comment}}
{{/if}}
Exec={{exec}}
Exec={{exec}} {{exec_arg}}
Icon={{icon}}
Name={{name}}
Terminal=false
Expand Down
18 changes: 16 additions & 2 deletions crates/packager/src/package/deb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
// <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html>
let file = &mut util::create_file(&desktop_file_path)?;

let mut handlebars = Handlebars::new();
Expand All @@ -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<String>,
}

// 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<String> = Vec::new();

if let Some(associations) = &config.file_associations {
if !associations.is_empty() {
exec_arg = Some("%F");
}
mime_type.extend(
associations
.iter()
Expand All @@ -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()
Expand All @@ -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,
Expand Down

0 comments on commit de4dcca

Please sign in to comment.