use super::{HandleToken, DESTINATION, PATH};
use crate::{helpers::call_request_method, Error, WindowIdentifier};
use zvariant_derive::{DeserializeDict, SerializeDict, TypeDict};
#[derive(SerializeDict, DeserializeDict, TypeDict, Clone, Debug, Default)]
struct ScreenshotOptions {
handle_token: HandleToken,
modal: Option<bool>,
interactive: Option<bool>,
}
impl ScreenshotOptions {
pub fn modal(mut self, modal: bool) -> Self {
self.modal = Some(modal);
self
}
pub fn interactive(mut self, interactive: bool) -> Self {
self.interactive = Some(interactive);
self
}
}
#[derive(DeserializeDict, SerializeDict, Clone, TypeDict, Debug)]
struct Screenshot {
uri: String,
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Clone, Debug, Default)]
struct PickColorOptions {
handle_token: HandleToken,
}
#[derive(SerializeDict, DeserializeDict, Clone, Copy, PartialEq, TypeDict)]
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) -> gtk3::gdk::RGBA {
gtk3::gdk::RGBA {
red: color.red(),
green: color.green(),
blue: color.blue(),
alpha: 1.0,
}
}
}
#[cfg(feature = "feature_gtk4")]
impl From<Color> for gtk4::gdk::RGBA {
fn from(color: Color) -> gtk4::gdk::RGBA {
gtk4::gdk::RGBA {
red: color.red() as f32,
green: color.green() as f32,
blue: color.blue() as f32,
alpha: 1_f32,
}
}
}
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()
}
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.Screenshot")]
pub struct ScreenshotProxy<'a>(zbus::azync::Proxy<'a>);
impl<'a> ScreenshotProxy<'a> {
pub async fn new(connection: &zbus::azync::Connection) -> Result<ScreenshotProxy<'a>, Error> {
let proxy = zbus::ProxyBuilder::new_bare(connection)
.interface("org.freedesktop.portal.Screenshot")
.path(PATH)?
.destination(DESTINATION)
.build_async()
.await?;
Ok(Self(proxy))
}
pub fn inner(&self) -> &zbus::azync::Proxy<'_> {
&self.0
}
#[doc(alias = "PickColor")]
pub async fn pick_color(&self, identifier: WindowIdentifier) -> Result<Color, Error> {
let options = PickColorOptions::default();
call_request_method(
&self.0,
&options.handle_token,
"PickColor",
&(identifier, &options),
)
.await
}
#[doc(alias = "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.0,
&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::azync::Connection::new_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::azync::Connection::new_session().await?;
let proxy = ScreenshotProxy::new(&connection).await?;
proxy.screenshot(identifier, interactive, modal).await
}