ashpd/desktop/remote_desktop.rs
1//! # Examples
2//!
3//! ```rust,no_run
4//! use ashpd::desktop::{
5//! PersistMode,
6//! remote_desktop::{DeviceType, KeyState, RemoteDesktop, SelectDevicesOptions},
7//! };
8//!
9//! async fn run() -> ashpd::Result<()> {
10//! let proxy = RemoteDesktop::new().await?;
11//! let session = proxy.create_session(Default::default()).await?;
12//! proxy
13//! .select_devices(
14//! &session,
15//! SelectDevicesOptions::default()
16//! .set_devices(DeviceType::Keyboard | DeviceType::Pointer),
17//! )
18//! .await?;
19//!
20//! let response = proxy
21//! .start(&session, None, Default::default())
22//! .await?
23//! .response()?;
24//! println!("{:#?}", response.devices());
25//!
26//! // 13 for Enter key code
27//! proxy
28//! .notify_keyboard_keycode(&session, 13, KeyState::Pressed, Default::default())
29//! .await?;
30//!
31//! Ok(())
32//! }
33//! ```
34//!
35//! You can also use the Remote Desktop portal with the ScreenCast one. In order
36//! to do so, you need to call
37//! [`Screencast::select_sources()`][select_sources]
38//! on the session created with
39//! [`RemoteDesktop::create_session()`][create_session]
40//!
41//! ```rust,no_run
42//! use ashpd::desktop::{
43//! PersistMode,
44//! remote_desktop::{DeviceType, KeyState, RemoteDesktop, SelectDevicesOptions},
45//! screencast::{CursorMode, Screencast, SelectSourcesOptions, SourceType},
46//! };
47//!
48//! async fn run() -> ashpd::Result<()> {
49//! let remote_desktop = RemoteDesktop::new().await?;
50//! let screencast = Screencast::new().await?;
51//! let session = remote_desktop.create_session(Default::default()).await?;
52//!
53//! remote_desktop
54//! .select_devices(
55//! &session,
56//! SelectDevicesOptions::default()
57//! .set_devices(DeviceType::Keyboard | DeviceType::Pointer),
58//! )
59//! .await?;
60//! screencast
61//! .select_sources(
62//! &session,
63//! SelectSourcesOptions::default()
64//! .set_cursor_mode(CursorMode::Metadata)
65//! .set_sources(SourceType::Monitor | SourceType::Window)
66//! .set_multiple(true)
67//! .set_persist_mode(PersistMode::DoNot),
68//! )
69//! .await?;
70//!
71//! let response = remote_desktop
72//! .start(&session, None, Default::default())
73//! .await?
74//! .response()?;
75//! println!("{:#?}", response.devices());
76//! println!("{:#?}", response.streams());
77//!
78//! // 13 for Enter key code
79//! remote_desktop
80//! .notify_keyboard_keycode(&session, 13, KeyState::Pressed, Default::default())
81//! .await?;
82//!
83//! Ok(())
84//! }
85//! ```
86//! [select_sources]: crate::desktop::screencast::Screencast::select_sources
87//! [create_session]: crate::desktop::remote_desktop::RemoteDesktop::create_session
88
89use std::os::fd::OwnedFd;
90
91use enumflags2::{BitFlags, bitflags};
92use serde::{Deserialize, Serialize};
93use serde_repr::{Deserialize_repr, Serialize_repr};
94use zbus::zvariant::{
95 self, Optional, Type,
96 as_value::{self, optional},
97};
98
99use super::{
100 HandleToken, PersistMode, Request, Session, screencast::Stream, session::SessionPortal,
101};
102use crate::{
103 Error, WindowIdentifier,
104 desktop::session::{CreateSessionOptions, CreateSessionResponse},
105 proxy::Proxy,
106};
107
108#[cfg_attr(feature = "glib", derive(glib::Enum))]
109#[cfg_attr(feature = "glib", enum_type(name = "AshpdKeyState"))]
110#[derive(Serialize_repr, Deserialize_repr, Copy, Clone, PartialEq, Eq, Debug, Type)]
111#[doc(alias = "XdpKeyState")]
112/// The keyboard key state.
113#[repr(u32)]
114pub enum KeyState {
115 #[doc(alias = "XDP_KEY_PRESSED")]
116 /// The key is pressed.
117 Pressed = 1,
118 #[doc(alias = "XDP_KEY_RELEASED")]
119 /// The key is released..
120 Released = 0,
121}
122
123#[bitflags]
124#[derive(Serialize_repr, Deserialize_repr, PartialEq, Eq, Debug, Clone, Copy, Type)]
125#[repr(u32)]
126#[doc(alias = "XdpDeviceType")]
127/// A bit flag for the available devices.
128pub enum DeviceType {
129 #[doc(alias = "XDP_DEVICE_KEYBOARD")]
130 /// A keyboard.
131 Keyboard,
132 #[doc(alias = "XDP_DEVICE_POINTER")]
133 /// A mouse pointer.
134 Pointer,
135 #[doc(alias = "XDP_DEVICE_TOUCHSCREEN")]
136 /// A touchscreen
137 Touchscreen,
138}
139
140#[cfg_attr(feature = "glib", derive(glib::Enum))]
141#[cfg_attr(feature = "glib", enum_type(name = "AshpdAxis"))]
142#[derive(Serialize_repr, Deserialize_repr, PartialEq, Eq, Debug, Clone, Copy, Type)]
143#[doc(alias = "XdpDiscreteAxis")]
144#[repr(u32)]
145/// The available axis.
146pub enum Axis {
147 #[doc(alias = "XDP_AXIS_VERTICAL_SCROLL")]
148 /// Vertical axis.
149 Vertical = 0,
150 #[doc(alias = "XDP_AXIS_HORIZONTAL_SCROLL")]
151 /// Horizontal axis.
152 Horizontal = 1,
153}
154
155#[derive(Serialize, Type, Debug, Default)]
156#[zvariant(signature = "dict")]
157/// Specified options for a [`RemoteDesktop::notify_keyboard_keycode`] request.
158pub struct NotifyKeyboardKeycodeOptions {}
159
160#[derive(Serialize, Type, Debug, Default)]
161#[zvariant(signature = "dict")]
162/// Specified options for a [`RemoteDesktop::notify_keyboard_keysym`] request.
163pub struct NotifyKeyboardKeysymOptions {}
164
165#[derive(Serialize, Type, Debug, Default)]
166#[zvariant(signature = "dict")]
167/// Specified options for a [`RemoteDesktop::notify_pointer_axis_discrete`]
168/// request.
169pub struct NotifyPointerAxisDiscreteOptions {}
170
171#[derive(Serialize, Type, Debug, Default)]
172#[zvariant(signature = "dict")]
173/// Specified options for a [`RemoteDesktop::notify_touch_up`] request.
174pub struct NotifyTouchUpOptions {}
175
176#[derive(Serialize, Type, Debug, Default)]
177#[zvariant(signature = "dict")]
178/// Specified options for a [`RemoteDesktop::notify_touch_down`] request.
179pub struct NotifyTouchDownOptions {}
180
181#[derive(Serialize, Type, Debug, Default)]
182#[zvariant(signature = "dict")]
183/// Specified options for a [`RemoteDesktop::notify_touch_motion`] request.
184pub struct NotifyTouchMotionOptions {}
185
186#[derive(Serialize, Type, Debug, Default)]
187#[zvariant(signature = "dict")]
188/// Specified options for a [`RemoteDesktop::notify_pointer_button`] request.
189pub struct NotifyPointerButtonOptions {}
190
191#[derive(Serialize, Type, Debug, Default)]
192#[zvariant(signature = "dict")]
193/// Specified options for a [`RemoteDesktop::notify_pointer_motion`] request.
194pub struct NotifyPointerMotionOptions {}
195
196#[derive(Serialize, Type, Debug, Default)]
197#[zvariant(signature = "dict")]
198/// Specified options for a [`RemoteDesktop::notify_pointer_motion_absolute`]
199/// request.
200pub struct NotifyPointerMotionAbsoluteOptions {}
201
202#[derive(Serialize, Type, Debug, Default)]
203#[zvariant(signature = "dict")]
204/// Specified options for a [`RemoteDesktop::notify_pointer_axis`] request.
205pub struct NotifyPointerAxisOptions {
206 #[serde(with = "as_value")]
207 finish: bool,
208}
209
210impl NotifyPointerAxisOptions {
211 /// Sets whether the axis event is the last one in a sequence.
212 pub fn set_finish(mut self, finish: bool) -> Self {
213 self.finish = finish;
214 self
215 }
216}
217
218#[derive(Serialize, Type, Debug, Default)]
219/// Specified options for a [`RemoteDesktop::select_devices`] request.
220#[zvariant(signature = "dict")]
221pub struct SelectDevicesOptions {
222 #[serde(with = "as_value")]
223 handle_token: HandleToken,
224 #[serde(with = "optional", skip_serializing_if = "Option::is_none")]
225 types: Option<BitFlags<DeviceType>>,
226 #[serde(with = "optional", skip_serializing_if = "Option::is_none")]
227 restore_token: Option<String>,
228 #[serde(with = "optional", skip_serializing_if = "Option::is_none")]
229 persist_mode: Option<PersistMode>,
230}
231
232impl SelectDevicesOptions {
233 /// Sets the device types to request remote controlling of.
234 pub fn set_devices(mut self, types: impl Into<Option<BitFlags<DeviceType>>>) -> Self {
235 self.types = types.into();
236 self
237 }
238
239 /// Sets the persist mode.
240 pub fn set_persist_mode(mut self, persist_mode: impl Into<Option<PersistMode>>) -> Self {
241 self.persist_mode = persist_mode.into();
242 self
243 }
244
245 /// Sets the restore token.
246 pub fn set_restore_token<'a>(mut self, token: impl Into<Option<&'a str>>) -> Self {
247 self.restore_token = token.into().map(ToOwned::to_owned);
248 self
249 }
250}
251
252#[derive(Serialize, Type, Debug, Default)]
253/// Specified options for a [`RemoteDesktop::start`] request.
254#[zvariant(signature = "dict")]
255pub struct StartOptions {
256 #[serde(with = "as_value")]
257 handle_token: HandleToken,
258}
259
260#[derive(Deserialize, Type, Debug, Default)]
261/// A response to a [`RemoteDesktop::select_devices`] request.
262#[zvariant(signature = "dict")]
263pub struct SelectedDevices {
264 #[serde(default, with = "as_value")]
265 devices: BitFlags<DeviceType>,
266 #[serde(default, with = "as_value")]
267 streams: Vec<Stream>,
268 #[serde(default, with = "optional")]
269 restore_token: Option<String>,
270 #[serde(default, with = "optional")]
271 clipboard_enabled: Option<bool>,
272}
273
274impl SelectedDevices {
275 /// The selected devices.
276 pub fn devices(&self) -> BitFlags<DeviceType> {
277 self.devices
278 }
279
280 /// The selected streams if a ScreenCast portal is used on the same session
281 pub fn streams(&self) -> &[Stream] {
282 &self.streams
283 }
284
285 /// The session restore token.
286 pub fn restore_token(&self) -> Option<&str> {
287 self.restore_token.as_deref()
288 }
289
290 /// Whether the clipboard was enabled.
291 pub fn is_clipboard_enabled(&self) -> bool {
292 self.clipboard_enabled.unwrap_or(false)
293 }
294}
295
296#[derive(Default, Debug, Serialize, Type)]
297#[zvariant(signature = "dict")]
298/// Specified options for a [`RemoteDesktop::connect_to_eis`] request.
299pub struct ConnectToEISOptions {}
300
301/// The interface lets sandboxed applications create remote desktop sessions.
302///
303/// Wrapper of the DBus interface: [`org.freedesktop.portal.RemoteDesktop`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html).
304#[derive(Debug)]
305#[doc(alias = "org.freedesktop.portal.RemoteDesktop")]
306pub struct RemoteDesktop(Proxy<'static>);
307
308impl RemoteDesktop {
309 /// Create a new instance of [`RemoteDesktop`].
310 pub async fn new() -> Result<Self, Error> {
311 let proxy = Proxy::new_desktop("org.freedesktop.portal.RemoteDesktop").await?;
312 Ok(Self(proxy))
313 }
314
315 /// Create a new instance of [`RemoteDesktop`].
316 pub async fn with_connection(connection: zbus::Connection) -> Result<Self, Error> {
317 let proxy =
318 Proxy::new_desktop_with_connection(connection, "org.freedesktop.portal.RemoteDesktop")
319 .await?;
320 Ok(Self(proxy))
321 }
322
323 /// Returns the version of the portal interface.
324 pub fn version(&self) -> u32 {
325 self.0.version()
326 }
327
328 /// Create a remote desktop session.
329 /// A remote desktop session is used to allow remote controlling a desktop
330 /// session. It can also be used together with a screen cast session.
331 ///
332 /// # Specifications
333 ///
334 /// See also [`CreateSession`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-createsession).
335 #[doc(alias = "CreateSession")]
336 #[doc(alias = "xdp_portal_create_remote_desktop_session")]
337 pub async fn create_session(
338 &self,
339 options: CreateSessionOptions,
340 ) -> Result<Session<Self>, Error> {
341 let (request, proxy) = futures_util::try_join!(
342 self.0.request::<CreateSessionResponse>(
343 &options.handle_token,
344 "CreateSession",
345 &options
346 ),
347 Session::from_unique_name(self.0.connection().clone(), &options.session_handle_token)
348 )?;
349 assert_eq!(proxy.path(), &request.response()?.session_handle.as_ref());
350 Ok(proxy)
351 }
352
353 /// Select input devices to remote control.
354 ///
355 /// # Arguments
356 ///
357 /// * `session` - A [`Session`], created with
358 /// [`create_session()`][`RemoteDesktop::create_session`].
359 /// * `types` - The device types to request remote controlling of.
360 ///
361 /// # Specifications
362 ///
363 /// See also [`SelectDevices`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-selectdevices).
364 #[doc(alias = "SelectDevices")]
365 pub async fn select_devices(
366 &self,
367 session: &Session<Self>,
368 options: SelectDevicesOptions,
369 ) -> Result<Request<()>, Error> {
370 self.0
371 .empty_request(&options.handle_token, "SelectDevices", &(session, &options))
372 .await
373 }
374
375 /// Start the remote desktop session.
376 ///
377 /// This will typically result in the portal presenting a dialog letting
378 /// the user select what to share, including devices and optionally screen
379 /// content if screen cast sources was selected.
380 ///
381 /// # Arguments
382 ///
383 /// * `session` - A [`Session`], created with
384 /// [`create_session()`][`RemoteDesktop::create_session`].
385 /// * `identifier` - The application window identifier.
386 ///
387 /// # Specifications
388 ///
389 /// See also [`Start`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-start).
390 #[doc(alias = "Start")]
391 pub async fn start(
392 &self,
393 session: &Session<Self>,
394 identifier: Option<&WindowIdentifier>,
395 options: StartOptions,
396 ) -> Result<Request<SelectedDevices>, Error> {
397 let identifier = Optional::from(identifier);
398 self.0
399 .request(
400 &options.handle_token,
401 "Start",
402 &(session, identifier, &options),
403 )
404 .await
405 }
406
407 /// Notify keyboard code.
408 ///
409 /// **Note** only works if [`DeviceType::Keyboard`] access was provided
410 /// after starting the session.
411 ///
412 /// # Arguments
413 ///
414 /// * `session` - A [`Session`], created with
415 /// [`create_session()`][`RemoteDesktop::create_session`].
416 /// * `keycode` - Keyboard code that was pressed or released.
417 /// * `state` - The new state of the keyboard code.
418 ///
419 /// # Specifications
420 ///
421 /// See also [`NotifyKeyboardKeycode`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifykeyboardkeycode).
422 #[doc(alias = "NotifyKeyboardKeycode")]
423 pub async fn notify_keyboard_keycode(
424 &self,
425 session: &Session<Self>,
426 keycode: i32,
427 state: KeyState,
428 options: NotifyKeyboardKeycodeOptions,
429 ) -> Result<(), Error> {
430 self.0
431 .call("NotifyKeyboardKeycode", &(session, options, keycode, state))
432 .await
433 }
434
435 /// Notify keyboard symbol.
436 ///
437 /// **Note** only works if [`DeviceType::Keyboard`] access was provided
438 /// after starting the session.
439 ///
440 /// # Arguments
441 ///
442 /// * `session` - A [`Session`], created with
443 /// [`create_session()`][`RemoteDesktop::create_session`].
444 /// * `keysym` - Keyboard symbol that was pressed or released.
445 /// * `state` - The new state of the keyboard code.
446 ///
447 /// # Specifications
448 ///
449 /// See also [`NotifyKeyboardKeysym`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifykeyboardkeysym).
450 #[doc(alias = "NotifyKeyboardKeysym")]
451 pub async fn notify_keyboard_keysym(
452 &self,
453 session: &Session<Self>,
454 keysym: i32,
455 state: KeyState,
456 options: NotifyKeyboardKeysymOptions,
457 ) -> Result<(), Error> {
458 self.0
459 .call("NotifyKeyboardKeysym", &(session, options, keysym, state))
460 .await
461 }
462
463 /// Notify about a new touch up event.
464 ///
465 /// **Note** only works if [`DeviceType::Touchscreen`] access was provided
466 /// after starting the session.
467 ///
468 /// # Arguments
469 ///
470 /// * `session` - A [`Session`], created with
471 /// [`create_session()`][`RemoteDesktop::create_session`].
472 /// * `slot` - Touch slot where touch point appeared.
473 ///
474 /// # Specifications
475 ///
476 /// See also [`NotifyTouchUp`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifytouchup).
477 #[doc(alias = "NotifyTouchUp")]
478 pub async fn notify_touch_up(
479 &self,
480 session: &Session<Self>,
481 slot: u32,
482 options: NotifyTouchUpOptions,
483 ) -> Result<(), Error> {
484 self.0
485 .call("NotifyTouchUp", &(session, options, slot))
486 .await
487 }
488
489 /// Notify about a new touch down event.
490 /// The (x, y) position represents the new touch point position in the
491 /// streams logical coordinate space.
492 ///
493 /// **Note** only works if [`DeviceType::Touchscreen`] access was provided
494 /// after starting the session.
495 ///
496 /// # Arguments
497 ///
498 /// * `session` - A [`Session`], created with
499 /// [`create_session()`][`RemoteDesktop::create_session`].
500 /// * `stream` - The PipeWire stream node the coordinate is relative to.
501 /// * `slot` - Touch slot where touch point appeared.
502 /// * `x` - Touch down x coordinate.
503 /// * `y` - Touch down y coordinate.
504 ///
505 /// # Specifications
506 ///
507 /// See also [`NotifyTouchDown`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifytouchdown).
508 #[doc(alias = "NotifyTouchDown")]
509 pub async fn notify_touch_down(
510 &self,
511 session: &Session<Self>,
512 stream: u32,
513 slot: u32,
514 x: f64,
515 y: f64,
516 options: NotifyTouchDownOptions,
517 ) -> Result<(), Error> {
518 self.0
519 .call("NotifyTouchDown", &(session, options, stream, slot, x, y))
520 .await
521 }
522
523 /// Notify about a new touch motion event.
524 /// The (x, y) position represents where the touch point position in the
525 /// streams logical coordinate space moved.
526 ///
527 /// **Note** only works if [`DeviceType::Touchscreen`] access was provided
528 /// after starting the session.
529 ///
530 /// # Arguments
531 ///
532 /// * `session` - A [`Session`], created with
533 /// [`create_session()`][`RemoteDesktop::create_session`].
534 /// * `stream` - The PipeWire stream node the coordinate is relative to.
535 /// * `slot` - Touch slot where touch point appeared.
536 /// * `x` - Touch motion x coordinate.
537 /// * `y` - Touch motion y coordinate.
538 ///
539 /// # Specifications
540 ///
541 /// See also [`NotifyTouchMotion`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifytouchmotion).
542 #[doc(alias = "NotifyTouchMotion")]
543 pub async fn notify_touch_motion(
544 &self,
545 session: &Session<Self>,
546 stream: u32,
547 slot: u32,
548 x: f64,
549 y: f64,
550 options: NotifyTouchMotionOptions,
551 ) -> Result<(), Error> {
552 self.0
553 .call("NotifyTouchMotion", &(session, options, stream, slot, x, y))
554 .await
555 }
556
557 /// Notify about a new absolute pointer motion event.
558 /// The (x, y) position represents the new pointer position in the streams
559 /// logical coordinate space.
560 ///
561 /// # Arguments
562 ///
563 /// * `session` - A [`Session`], created with
564 /// [`create_session()`][`RemoteDesktop::create_session`].
565 /// * `stream` - The PipeWire stream node the coordinate is relative to.
566 /// * `x` - Pointer motion x coordinate.
567 /// * `y` - Pointer motion y coordinate.
568 ///
569 /// # Specifications
570 ///
571 /// See also [`NotifyPointerMotionAbsolute`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifypointermotionabsolute).
572 #[doc(alias = "NotifyPointerMotionAbsolute")]
573 pub async fn notify_pointer_motion_absolute(
574 &self,
575 session: &Session<Self>,
576 stream: u32,
577 x: f64,
578 y: f64,
579 options: NotifyPointerMotionAbsoluteOptions,
580 ) -> Result<(), Error> {
581 self.0
582 .call(
583 "NotifyPointerMotionAbsolute",
584 &(session, options, stream, x, y),
585 )
586 .await
587 }
588
589 /// Notify about a new relative pointer motion event.
590 /// The (dx, dy) vector represents the new pointer position in the streams
591 /// logical coordinate space.
592 ///
593 /// # Arguments
594 ///
595 /// * `session` - A [`Session`], created with
596 /// [`create_session()`][`RemoteDesktop::create_session`].
597 /// * `dx` - Relative movement on the x axis.
598 /// * `dy` - Relative movement on the y axis.
599 ///
600 /// # Specifications
601 ///
602 /// See also [`NotifyPointerMotion`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifypointermotion).
603 #[doc(alias = "NotifyPointerMotion")]
604 pub async fn notify_pointer_motion(
605 &self,
606 session: &Session<Self>,
607 dx: f64,
608 dy: f64,
609 options: NotifyPointerMotionOptions,
610 ) -> Result<(), Error> {
611 self.0
612 .call("NotifyPointerMotion", &(session, options, dx, dy))
613 .await
614 }
615
616 /// Notify pointer button.
617 /// The pointer button is encoded according to Linux Evdev button codes.
618 ///
619 ///
620 /// **Note** only works if [`DeviceType::Pointer`] access was provided after
621 /// starting the session.
622 ///
623 /// # Arguments
624 ///
625 /// * `session` - A [`Session`], created with
626 /// [`create_session()`][`RemoteDesktop::create_session`].
627 /// * `button` - The pointer button was pressed or released.
628 /// * `state` - The new state of the keyboard code.
629 ///
630 /// # Specifications
631 ///
632 /// See also [`NotifyPointerButton`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifypointerbutton).
633 #[doc(alias = "NotifyPointerButton")]
634 pub async fn notify_pointer_button(
635 &self,
636 session: &Session<Self>,
637 button: i32,
638 state: KeyState,
639 options: NotifyPointerButtonOptions,
640 ) -> Result<(), Error> {
641 self.0
642 .call("NotifyPointerButton", &(session, options, button, state))
643 .await
644 }
645
646 /// Notify pointer axis discrete.
647 ///
648 /// **Note** only works if [`DeviceType::Pointer`] access was provided after
649 /// starting the session.
650 ///
651 /// # Arguments
652 ///
653 /// * `session` - A [`Session`], created with
654 /// [`create_session()`][`RemoteDesktop::create_session`].
655 /// * `axis` - The axis that was scrolled.
656 ///
657 /// # Specifications
658 ///
659 /// See also [`NotifyPointerAxisDiscrete`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifypointeraxisdiscrete).
660 #[doc(alias = "NotifyPointerAxisDiscrete")]
661 pub async fn notify_pointer_axis_discrete(
662 &self,
663 session: &Session<Self>,
664 axis: Axis,
665 steps: i32,
666 options: NotifyPointerAxisDiscreteOptions,
667 ) -> Result<(), Error> {
668 self.0
669 .call(
670 "NotifyPointerAxisDiscrete",
671 &(session, options, axis, steps),
672 )
673 .await
674 }
675
676 /// Notify pointer axis.
677 /// The axis movement from a "smooth scroll" device, such as a touchpad.
678 /// When applicable, the size of the motion delta should be equivalent to
679 /// the motion vector of a pointer motion done using the same advice.
680 ///
681 ///
682 /// **Note** only works if [`DeviceType::Pointer`] access was provided after
683 /// starting the session.
684 ///
685 /// # Arguments
686 ///
687 /// * `session` - A [`Session`], created with
688 /// [`create_session()`][`RemoteDesktop::create_session`].
689 /// * `dx` - Relative axis movement on the x axis.
690 /// * `dy` - Relative axis movement on the y axis.
691 /// * `finish` - Whether it is the last axis event.
692 ///
693 /// # Specifications
694 ///
695 /// See also [`NotifyPointerAxis`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-notifypointeraxis).
696 #[doc(alias = "NotifyPointerAxis")]
697 pub async fn notify_pointer_axis(
698 &self,
699 session: &Session<Self>,
700 dx: f64,
701 dy: f64,
702 options: NotifyPointerAxisOptions,
703 ) -> Result<(), Error> {
704 self.0
705 .call("NotifyPointerAxis", &(session, options, dx, dy))
706 .await
707 }
708
709 /// Connect to EIS.
710 ///
711 /// **Note** only succeeds if called after [`RemoteDesktop::start`].
712 ///
713 /// Requires RemoteDesktop version 2.
714 ///
715 /// # Arguments
716 ///
717 /// * `session` - A [`Session`], created with
718 /// [`create_session()`][`RemoteDesktop::create_session`].
719 ///
720 /// # Required version
721 ///
722 /// The method requires the 2nd version implementation of the portal and
723 /// would fail with [`Error::RequiresVersion`] otherwise.
724 ///
725 /// # Specifications
726 ///
727 /// See also [`ConnectToEIS`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-connecttoeis).
728 #[doc(alias = "ConnectToEIS")]
729 pub async fn connect_to_eis(
730 &self,
731 session: &Session<Self>,
732 options: ConnectToEISOptions,
733 ) -> Result<OwnedFd, Error> {
734 let fd = self
735 .0
736 .call_versioned::<zvariant::OwnedFd>("ConnectToEIS", &(session, options), 2)
737 .await?;
738 Ok(fd.into())
739 }
740
741 /// Available source types.
742 ///
743 /// # Specifications
744 ///
745 /// See also [`AvailableDeviceTypes`](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.RemoteDesktop.html#org-freedesktop-portal-remotedesktop-availabledevicetypes).
746 #[doc(alias = "AvailableDeviceTypes")]
747 pub async fn available_device_types(&self) -> Result<BitFlags<DeviceType>, Error> {
748 self.0.property("AvailableDeviceTypes").await
749 }
750}
751
752impl std::ops::Deref for RemoteDesktop {
753 type Target = zbus::Proxy<'static>;
754
755 fn deref(&self) -> &Self::Target {
756 &self.0
757 }
758}
759
760impl crate::Sealed for RemoteDesktop {}
761impl SessionPortal for RemoteDesktop {}
762#[cfg(feature = "clipboard")]
763impl crate::desktop::clipboard::IsClipboardSession for RemoteDesktop {}
764#[cfg(feature = "screencast")]
765impl crate::desktop::screencast::IsScreencastSession for RemoteDesktop {}