diff --git a/src/activation_token/mod.rs b/src/activation_token/mod.rs new file mode 100644 index 000000000..049bc6380 --- /dev/null +++ b/src/activation_token/mod.rs @@ -0,0 +1,42 @@ +use std::ops::Deref; + +use serde::{Deserialize, Serialize}; +use zbus::zvariant::Type; + +/// A token that can be used to activate an application. +/// +/// No guarantees are made for the token structure. +#[derive(Debug, Deserialize, Serialize, Type, PartialEq, Eq, Hash, Clone)] +pub struct ActivationToken(String); + +impl From for ActivationToken { + fn from(value: String) -> Self { + ActivationToken(value) + } +} + +impl From for String { + fn from(value: ActivationToken) -> String { + value.0 + } +} + +impl Deref for ActivationToken { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.0.as_str() + } +} + +impl AsRef for ActivationToken { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} + +impl std::fmt::Display for ActivationToken { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_ref()) + } +} diff --git a/src/desktop/dynamic_launcher.rs b/src/desktop/dynamic_launcher.rs index db8e03fa1..250c27742 100644 --- a/src/desktop/dynamic_launcher.rs +++ b/src/desktop/dynamic_launcher.rs @@ -58,7 +58,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use zbus::zvariant::{self, DeserializeDict, OwnedValue, SerializeDict, Type, Value}; use super::{HandleToken, Icon, Request}; -use crate::{proxy::Proxy, Error, WindowIdentifier}; +use crate::{proxy::Proxy, ActivationToken, Error, WindowIdentifier}; #[bitflags] #[derive(Default, Serialize_repr, Deserialize_repr, PartialEq, Eq, Debug, Copy, Clone, Type)] @@ -194,6 +194,25 @@ impl std::fmt::Debug for PrepareInstallResponse { } } +#[derive(SerializeDict, Type, Debug, Default)] +#[zvariant(signature = "dict")] +/// Options to pass to [`DynamicLauncherProxy::launch`] +pub struct LaunchOptions { + activation_token: Option, +} + +impl LaunchOptions { + /// Sets the token that can be used to activate the chosen application. + #[must_use] + pub fn activation_token( + mut self, + activation_token: impl Into>, + ) -> Self { + self.activation_token = activation_token.into(); + self + } +} + #[derive(Debug)] /// Wrong type of [`crate::desktop::Icon`] was used. pub struct UnexpectedIconError; @@ -321,9 +340,7 @@ impl<'a> DynamicLauncherProxy<'a> { /// See also [`Launch`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.DynamicLauncher.html#org-freedesktop-portal-dynamiclauncher-launch). #[doc(alias = "Launch")] #[doc(alias = "xdp_portal_dynamic_launcher_launch")] - pub async fn launch(&self, desktop_file_id: &str) -> Result<(), Error> { - // TODO: handle activation_token - let options: HashMap<&str, zvariant::Value<'_>> = HashMap::new(); + pub async fn launch(&self, desktop_file_id: &str, options: LaunchOptions) -> Result<(), Error> { self.0.call("Launch", &(desktop_file_id, &options)).await } diff --git a/src/desktop/email.rs b/src/desktop/email.rs index c4416b446..47cb2007e 100644 --- a/src/desktop/email.rs +++ b/src/desktop/email.rs @@ -30,7 +30,7 @@ use serde::Serialize; use zbus::zvariant::{self, SerializeDict, Type}; use super::{HandleToken, Request}; -use crate::{proxy::Proxy, Error, WindowIdentifier}; +use crate::{proxy::Proxy, ActivationToken, Error, WindowIdentifier}; #[derive(SerializeDict, Type, Debug, Default)] #[zvariant(signature = "dict")] @@ -43,8 +43,7 @@ struct EmailOptions { subject: Option, body: Option, attachment_fds: Option>, - // TODO Expose activation_token in the api - activation_token: Option, + activation_token: Option, } #[derive(Debug)] @@ -178,11 +177,13 @@ impl EmailRequest { } // TODO Added in version 4 of the interface. - /// Sets the activation token. - #[allow(dead_code)] + /// Sets the token that can be used to activate the chosen application. #[must_use] - fn activation_token<'a>(mut self, activation_token: impl Into>) -> Self { - self.options.activation_token = activation_token.into().map(ToOwned::to_owned); + pub fn activation_token( + mut self, + activation_token: impl Into>, + ) -> Self { + self.options.activation_token = activation_token.into(); self } diff --git a/src/desktop/open_uri.rs b/src/desktop/open_uri.rs index 6530e61c8..05a38dd30 100644 --- a/src/desktop/open_uri.rs +++ b/src/desktop/open_uri.rs @@ -57,13 +57,13 @@ use url::Url; use zbus::zvariant::{Fd, SerializeDict, Type}; use super::{HandleToken, Request}; -use crate::{proxy::Proxy, Error, WindowIdentifier}; +use crate::{proxy::Proxy, ActivationToken, Error, WindowIdentifier}; #[derive(SerializeDict, Type, Debug, Default)] #[zvariant(signature = "dict")] struct OpenDirOptions { handle_token: HandleToken, - activation_token: Option, + activation_token: Option, } #[derive(SerializeDict, Type, Debug, Default)] @@ -72,7 +72,7 @@ struct OpenFileOptions { handle_token: HandleToken, writeable: Option, ask: Option, - activation_token: Option, + activation_token: Option, } #[derive(Debug)] @@ -171,6 +171,16 @@ impl OpenFileRequest { self } + /// Sets the token that can be used to activate the chosen application. + #[must_use] + pub fn activation_token( + mut self, + activation_token: impl Into>, + ) -> Self { + self.options.activation_token = activation_token.into(); + self + } + /// Send the request for a file. pub async fn send_file(self, file: &BorrowedFd<'_>) -> Result, Error> { let proxy = OpenURIProxy::new().await?; @@ -203,6 +213,16 @@ impl OpenDirectoryRequest { self } + /// Sets the token that can be used to activate the chosen application. + #[must_use] + pub fn activation_token( + mut self, + activation_token: impl Into>, + ) -> Self { + self.options.activation_token = activation_token.into(); + self + } + /// Send the request. pub async fn send(self, directory: &BorrowedFd<'_>) -> Result, Error> { let proxy = OpenURIProxy::new().await?; diff --git a/src/lib.rs b/src/lib.rs index fe632a280..25f424128 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ pub type Result = std::result::Result; static IS_SANDBOXED: OnceLock = OnceLock::new(); +mod activation_token; /// Interact with the user's desktop such as taking a screenshot, setting a /// background or querying the user's location. pub mod desktop; @@ -22,6 +23,7 @@ pub mod documents; mod error; mod window_identifier; +pub use self::activation_token::ActivationToken; pub use self::window_identifier::WindowIdentifier; mod app_id; pub use self::app_id::AppID;