Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(debian): auto-add an Exec arg (field code) in the .desktop file #256

Merged
merged 4 commits into from
Jul 2, 2024
Merged
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
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");
amr-crabnebula marked this conversation as resolved.
Show resolved Hide resolved
}
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
Loading