use std::fmt::Debug;
use zbus::zvariant::{DeserializeDict, SerializeDict, Type};
use super::{HandleToken, DESTINATION, PATH};
use crate::{helpers::call_request_method, Error, WindowIdentifier};
#[derive(SerializeDict, DeserializeDict, Type, Clone, Debug, Default)]
#[zvariant(signature = "dict")]
struct ScreenshotOptions {
handle_token: HandleToken,
modal: Option<bool>,
interactive: Option<bool>,
}
impl ScreenshotOptions {
#[must_use]
pub fn modal(mut self, modal: bool) -> Self {
self.modal = Some(modal);
self
}
#[must_use]
pub fn interactive(mut self, interactive: bool) -> Self {
self.interactive = Some(interactive);
self
}
}
#[derive(DeserializeDict, SerializeDict, Clone, Type)]
#[zvariant(signature = "dict")]
struct Screenshot {
uri: String,
}
impl Debug for Screenshot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.uri)
}
}
#[derive(SerializeDict, DeserializeDict, Type, Clone, Debug, Default)]
#[zvariant(signature = "dict")]
struct PickColorOptions {
handle_token: HandleToken,
}
#[derive(SerializeDict, DeserializeDict, Clone, Copy, PartialEq, Type)]
#[zvariant(signature = "dict")]
pub struct Color {
color: ([f64; 3]),
}
impl Color {
pub fn red(&self) -> f64 {
self.color[0]
}
pub fn green(&self) -> f64 {
self.color[1]
}
pub fn blue(&self) -> f64 {
self.color[2]
}
}
#[cfg(feature = "feature_gtk3")]
impl From<Color> for gtk3::gdk::RGBA {
fn from(color: Color) -> Self {
gtk3::gdk::RGBA::new(color.red(), color.green(), color.blue(), 1.0)
}
}
#[cfg(feature = "feature_gtk4")]
impl From<Color> for gtk4::gdk::RGBA {
fn from(color: Color) -> Self {
gtk4::gdk::RGBA::builder()
.red(color.red() as f32)
.green(color.green() as f32)
.blue(color.blue() as f32)
.build()
}
}
impl std::fmt::Debug for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Color")
.field("red", &self.red())
.field("green", &self.green())
.field("blue", &self.blue())
.finish()
}
}
impl std::fmt::Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"({}, {}, {})",
self.red(),
self.green(),
self.blue()
))
}
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.Screenshot")]
pub struct ScreenshotProxy<'a>(zbus::Proxy<'a>);
impl<'a> ScreenshotProxy<'a> {
pub async fn new(connection: &zbus::Connection) -> Result<ScreenshotProxy<'a>, Error> {
let proxy = zbus::ProxyBuilder::new_bare(connection)
.interface("org.freedesktop.portal.Screenshot")?
.path(PATH)?
.destination(DESTINATION)?
.build()
.await?;
Ok(Self(proxy))
}
pub fn inner(&self) -> &zbus::Proxy<'_> {
&self.0
}
#[doc(alias = "PickColor")]
#[doc(alias = "xdp_portal_pick_color")]
pub async fn pick_color(&self, identifier: &WindowIdentifier) -> Result<Color, Error> {
let options = PickColorOptions::default();
call_request_method(
self.inner(),
&options.handle_token,
"PickColor",
&(&identifier, &options),
)
.await
}
#[doc(alias = "Screenshot")]
#[doc(alias = "xdp_portal_take_screenshot")]
pub async fn screenshot(
&self,
identifier: &WindowIdentifier,
interactive: bool,
modal: bool,
) -> Result<String, Error> {
let options = ScreenshotOptions::default()
.interactive(interactive)
.modal(modal);
let response: Screenshot = call_request_method(
self.inner(),
&options.handle_token,
"Screenshot",
&(&identifier, &options),
)
.await?;
Ok(response.uri)
}
}
#[doc(alias = "xdp_portal_pick_color")]
pub async fn pick_color(identifier: &WindowIdentifier) -> Result<Color, Error> {
let connection = zbus::Connection::session().await?;
let proxy = ScreenshotProxy::new(&connection).await?;
proxy.pick_color(identifier).await
}
#[doc(alias = "xdp_portal_take_screenshot")]
pub async fn take(
identifier: &WindowIdentifier,
interactive: bool,
modal: bool,
) -> Result<String, Error> {
let connection = zbus::Connection::session().await?;
let proxy = ScreenshotProxy::new(&connection).await?;
proxy.screenshot(identifier, interactive, modal).await
}