ashpd/desktop/
clipboard.rs1use std::collections::HashMap;
7
8use futures_util::{Stream, StreamExt};
9use zbus::zvariant::{DeserializeDict, OwnedFd, OwnedObjectPath, SerializeDict, Type, Value};
10
11use super::{remote_desktop::RemoteDesktop, Session};
12use crate::{proxy::Proxy, Result};
13
14#[derive(Debug, Type, SerializeDict)]
15#[zvariant(signature = "dict")]
16struct SetSelectionOptions<'a> {
17 mime_types: &'a [&'a str],
18}
19
20#[derive(Debug, Type, DeserializeDict)]
21#[zvariant(signature = "dict")]
22pub struct SelectionOwnerChanged {
24 mime_types: Option<Vec<String>>,
25 session_is_owner: Option<bool>,
26}
27
28impl SelectionOwnerChanged {
29 pub fn session_is_owner(&self) -> Option<bool> {
31 self.session_is_owner
32 }
33
34 pub fn mime_types(&self) -> Vec<String> {
36 self.mime_types.clone().unwrap_or_default()
37 }
38}
39
40#[doc(alias = "org.freedesktop.portal.Clipboard")]
41pub struct Clipboard<'a>(Proxy<'a>);
43
44impl<'a> Clipboard<'a> {
45 pub async fn new() -> Result<Clipboard<'a>> {
47 Ok(Self(
48 Proxy::new_desktop("org.freedesktop.portal.Clipboard").await?,
49 ))
50 }
51
52 #[doc(alias = "RequestClipboard")]
56 pub async fn request(&self, session: &Session<'_, RemoteDesktop<'_>>) -> Result<()> {
57 let options: HashMap<&str, Value<'_>> = HashMap::default();
58 self.0
59 .call_method("RequestClipboard", &(session, options))
60 .await?;
61 Ok(())
62 }
63
64 #[doc(alias = "SetSelection")]
68 pub async fn set_selection(
69 &self,
70 session: &Session<'_, RemoteDesktop<'_>>,
71 mime_types: &[&str],
72 ) -> Result<()> {
73 let options = SetSelectionOptions { mime_types };
74 self.0
75 .call::<()>("SetSelection", &(session, options))
76 .await?;
77
78 Ok(())
79 }
80
81 #[doc(alias = "SelectionWrite")]
85 pub async fn selection_write(
86 &self,
87 session: &Session<'_, RemoteDesktop<'_>>,
88 serial: u32,
89 ) -> Result<OwnedFd> {
90 let fd = self
91 .0
92 .call::<OwnedFd>("SelectionWrite", &(session, serial))
93 .await?;
94 Ok(fd)
95 }
96
97 #[doc(alias = "SelectionWriteDone")]
101 pub async fn selection_write_done(
102 &self,
103 session: &Session<'_, RemoteDesktop<'_>>,
104 serial: u32,
105 success: bool,
106 ) -> Result<()> {
107 self.0
108 .call("SelectionWriteDone", &(session, serial, success))
109 .await
110 }
111
112 #[doc(alias = "SelectionRead")]
116 pub async fn selection_read(
117 &self,
118 session: &Session<'_, RemoteDesktop<'_>>,
119 mime_type: &str,
120 ) -> Result<OwnedFd> {
121 let fd = self
122 .0
123 .call::<OwnedFd>("SelectionRead", &(session, mime_type))
124 .await?;
125 Ok(fd)
126 }
127
128 #[doc(alias = "SelectionOwnerChanged")]
133 pub async fn receive_selection_owner_changed(
134 &self,
135 ) -> Result<impl Stream<Item = (Session<RemoteDesktop>, SelectionOwnerChanged)>> {
136 Ok(self
137 .0
138 .signal::<(OwnedObjectPath, SelectionOwnerChanged)>("SelectionOwnerChanged")
139 .await?
140 .filter_map(|(p, o)| async move { Session::new(p).await.map(|s| (s, o)).ok() }))
141 }
142
143 #[doc(alias = "SelectionTransfer")]
147 pub async fn receive_selection_transfer(
148 &self,
149 ) -> Result<impl Stream<Item = (Session<RemoteDesktop>, String, u32)>> {
150 Ok(self
151 .0
152 .signal::<(OwnedObjectPath, String, u32)>("SelectionTransfer")
153 .await?
154 .filter_map(|(p, mime_type, serial)| async move {
155 Session::new(p)
156 .await
157 .map(|session| (session, mime_type, serial))
158 .ok()
159 }))
160 }
161}
162
163impl<'a> std::ops::Deref for Clipboard<'a> {
164 type Target = zbus::Proxy<'a>;
165
166 fn deref(&self) -> &Self::Target {
167 &self.0
168 }
169}