Skip to main content

smithay_client_toolkit/primary_selection/
offer.rs

1use std::{
2    os::unix::io::{AsFd, OwnedFd},
3    sync::Mutex,
4};
5
6use crate::reexports::client::{Connection, QueueHandle, Proxy};
7use crate::reexports::protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1;
8
9use crate::data_device_manager::ReadPipe;
10use crate::dispatch2::Dispatch2;
11
12/// Wrapper around the [`ZwpPrimarySelectionOfferV1`].
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct PrimarySelectionOffer {
15    pub(crate) offer: ZwpPrimarySelectionOfferV1,
16}
17
18impl PrimarySelectionOffer {
19    /// Inspect the mime types available on the given offer.
20    pub fn with_mime_types<T, F: Fn(&[String]) -> T>(&self, callback: F) -> T {
21        let mime_types =
22            self.offer.data::<PrimarySelectionOfferData>().unwrap().mimes.lock().unwrap();
23        callback(mime_types.as_ref())
24    }
25
26    /// Request to receive the data of a given mime type.
27    ///
28    /// You can call this function several times.
29    ///
30    /// Note that you should *not* read the contents right away in a
31    /// blocking way, as you may deadlock your application doing so.
32    /// At least make sure you flush your events to the server before
33    /// doing so.
34    ///
35    /// Fails if too many file descriptors were already open and a pipe
36    /// could not be created.
37    pub fn receive(&self, mime_type: String) -> std::io::Result<ReadPipe> {
38        use rustix::pipe::{pipe_with, PipeFlags};
39        // create a pipe
40        let (readfd, writefd) = pipe_with(PipeFlags::CLOEXEC)?;
41
42        self.receive_to_fd(mime_type, writefd);
43
44        Ok(ReadPipe::from(readfd))
45    }
46
47    /// Request to receive the data of a given mime type, writen to `writefd`.
48    ///
49    /// The provided file destructor must be a valid FD for writing, and will be closed
50    /// once the contents are written.
51    pub fn receive_to_fd(&self, mime_type: String, writefd: OwnedFd) {
52        self.offer.receive(mime_type, writefd.as_fd());
53    }
54}
55
56impl<State> Dispatch2<ZwpPrimarySelectionOfferV1, State> for PrimarySelectionOfferData {
57    fn event(
58        &self,
59        _: &mut State,
60        _: &ZwpPrimarySelectionOfferV1,
61        event: <ZwpPrimarySelectionOfferV1 as wayland_client::Proxy>::Event,
62        _: &Connection,
63        _: &QueueHandle<State>,
64    ) {
65        use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::Event;
66        match event {
67            Event::Offer { mime_type } => {
68                self.mimes.lock().unwrap().push(mime_type);
69            }
70            _ => unreachable!(),
71        }
72    }
73}
74
75/// The data associated with the [`ZwpPrimarySelectionOfferV1`].
76#[derive(Debug, Default)]
77pub struct PrimarySelectionOfferData {
78    mimes: Mutex<Vec<String>>,
79}