use serde::{Deserialize, Serialize};
use zbus::zvariant::{
Optional, Type,
as_value::{self, optional},
};
use super::{HandleToken, Request};
use crate::{Error, WindowIdentifier, proxy::Proxy};
#[derive(Serialize, Type, Debug, Default)]
#[zvariant(signature = "dict")]
pub struct BackgroundRequestOptions {
#[serde(with = "as_value")]
handle_token: HandleToken,
#[serde(with = "optional", skip_serializing_if = "Option::is_none")]
reason: Option<String>,
#[serde(with = "optional", skip_serializing_if = "Option::is_none")]
autostart: Option<bool>,
#[serde(
with = "optional",
rename = "dbus-activatable",
skip_serializing_if = "Option::is_none"
)]
dbus_activatable: Option<bool>,
#[serde(
with = "as_value",
rename = "commandline",
skip_serializing_if = "Vec::is_empty"
)]
command: Vec<String>,
}
impl BackgroundRequestOptions {
#[must_use]
pub fn set_auto_start(mut self, auto_start: impl Into<Option<bool>>) -> Self {
self.autostart = auto_start.into();
self
}
#[must_use]
pub fn set_dbus_activatable(mut self, dbus_activatable: impl Into<Option<bool>>) -> Self {
self.dbus_activatable = dbus_activatable.into();
self
}
#[must_use]
pub fn set_command<P: IntoIterator<Item = I>, I: AsRef<str> + Type + Serialize>(
mut self,
command: P,
) -> Self {
self.command = command.into_iter().map(|s| s.as_ref().to_owned()).collect();
self
}
#[must_use]
pub fn set_reason<'a>(mut self, reason: impl Into<Option<&'a str>>) -> Self {
self.reason = reason.into().map(ToOwned::to_owned);
self
}
}
#[derive(Deserialize, Type, Debug)]
#[zvariant(signature = "dict")]
pub struct Background {
#[serde(with = "as_value")]
background: bool,
#[serde(with = "as_value")]
autostart: bool,
}
impl Background {
pub fn request() -> BackgroundRequest {
BackgroundRequest::default()
}
pub fn run_in_background(&self) -> bool {
self.background
}
pub fn auto_start(&self) -> bool {
self.autostart
}
}
#[derive(Serialize, Type, Debug, Default)]
#[zvariant(signature = "dict")]
pub struct SetStatusOptions {
#[serde(with = "as_value")]
message: String,
}
impl SetStatusOptions {
pub fn set_message(mut self, message: &str) -> Self {
self.message = message.to_owned();
self
}
}
#[doc(alias = "org.freedesktop.portal.Background")]
pub struct BackgroundProxy(Proxy<'static>);
impl BackgroundProxy {
pub async fn new() -> Result<BackgroundProxy, Error> {
let proxy = Proxy::new_desktop("org.freedesktop.portal.Background").await?;
Ok(Self(proxy))
}
pub async fn with_connection(connection: zbus::Connection) -> Result<BackgroundProxy, Error> {
let proxy =
Proxy::new_desktop_with_connection(connection, "org.freedesktop.portal.Background")
.await?;
Ok(Self(proxy))
}
pub fn version(&self) -> u32 {
self.0.version()
}
#[doc(alias = "SetStatus")]
pub async fn set_status(&self, options: SetStatusOptions) -> Result<(), Error> {
self.0.call_versioned("SetStatus", &(options), 2).await
}
#[doc(alias = "RequestBackground")]
pub async fn request_background(
&self,
identifier: Option<&WindowIdentifier>,
options: BackgroundRequestOptions,
) -> Result<Request<Background>, Error> {
let identifier = Optional::from(identifier);
self.0
.request(
&options.handle_token,
"RequestBackground",
(identifier, &options),
)
.await
}
}
impl std::ops::Deref for BackgroundProxy {
type Target = zbus::Proxy<'static>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[doc(alias = "xdp_portal_request_background")]
#[derive(Debug, Default)]
pub struct BackgroundRequest {
identifier: Option<WindowIdentifier>,
options: BackgroundRequestOptions,
}
impl BackgroundRequest {
#[must_use]
pub fn identifier(mut self, identifier: impl Into<Option<WindowIdentifier>>) -> Self {
self.identifier = identifier.into();
self
}
#[must_use]
pub fn auto_start(mut self, auto_start: impl Into<Option<bool>>) -> Self {
self.options.autostart = auto_start.into();
self
}
#[must_use]
pub fn dbus_activatable(mut self, dbus_activatable: impl Into<Option<bool>>) -> Self {
self.options.dbus_activatable = dbus_activatable.into();
self
}
#[must_use]
pub fn command<P: IntoIterator<Item = I>, I: AsRef<str> + Type + Serialize>(
mut self,
command: P,
) -> Self {
self.options.command = command.into_iter().map(|s| s.as_ref().to_owned()).collect();
self
}
#[must_use]
pub fn reason<'a>(mut self, reason: impl Into<Option<&'a str>>) -> Self {
self.options.reason = reason.into().map(ToOwned::to_owned);
self
}
pub async fn send(self) -> Result<Request<Background>, Error> {
let proxy = BackgroundProxy::new().await?;
proxy
.request_background(self.identifier.as_ref(), self.options)
.await
}
}