smithay_client_toolkit/data_device_manager/
mod.rs

1use crate::error::GlobalError;
2use crate::globals::{GlobalData, ProvidesBoundGlobal};
3use crate::reexports::client::{
4    globals::{BindError, GlobalList},
5    protocol::{
6        wl_data_device,
7        wl_data_device_manager::{self, DndAction, WlDataDeviceManager},
8        wl_data_source::WlDataSource,
9        wl_seat::WlSeat,
10    },
11    Connection, Dispatch, Proxy, QueueHandle,
12};
13
14pub mod data_device;
15pub mod data_offer;
16pub mod data_source;
17mod read_pipe;
18mod write_pipe;
19
20pub use read_pipe::*;
21pub use write_pipe::*;
22
23use data_device::{DataDevice, DataDeviceData};
24use data_source::{CopyPasteSource, DataSourceData, DragSource};
25
26#[derive(Debug)]
27pub struct DataDeviceManagerState {
28    manager: WlDataDeviceManager,
29}
30
31impl DataDeviceManagerState {
32    pub fn bind<State>(globals: &GlobalList, qh: &QueueHandle<State>) -> Result<Self, BindError>
33    where
34        State: Dispatch<WlDataDeviceManager, GlobalData, State> + 'static,
35    {
36        let manager = globals.bind(qh, 1..=3, GlobalData)?;
37        Ok(Self { manager })
38    }
39
40    pub fn data_device_manager(&self) -> &WlDataDeviceManager {
41        &self.manager
42    }
43
44    /// creates a data source for copy paste
45    pub fn create_copy_paste_source<D, T: ToString>(
46        &self,
47        qh: &QueueHandle<D>,
48        mime_types: impl IntoIterator<Item = T>,
49    ) -> CopyPasteSource
50    where
51        D: Dispatch<WlDataSource, DataSourceData> + 'static,
52    {
53        CopyPasteSource { inner: self.create_data_source(qh, mime_types, None) }
54    }
55
56    /// creates a data source for drag and drop
57    pub fn create_drag_and_drop_source<D, T: ToString>(
58        &self,
59        qh: &QueueHandle<D>,
60        mime_types: impl IntoIterator<Item = T>,
61        dnd_actions: DndAction,
62    ) -> DragSource
63    where
64        D: Dispatch<WlDataSource, DataSourceData> + 'static,
65    {
66        DragSource { inner: self.create_data_source(qh, mime_types, Some(dnd_actions)) }
67    }
68
69    /// creates a data source
70    fn create_data_source<D, T: ToString>(
71        &self,
72        qh: &QueueHandle<D>,
73        mime_types: impl IntoIterator<Item = T>,
74        dnd_actions: Option<DndAction>,
75    ) -> WlDataSource
76    where
77        D: Dispatch<WlDataSource, DataSourceData> + 'static,
78    {
79        let source = self.manager.create_data_source(qh, Default::default());
80
81        for mime in mime_types {
82            source.offer(mime.to_string());
83        }
84
85        if self.manager.version() >= 3 {
86            if let Some(dnd_actions) = dnd_actions {
87                source.set_actions(dnd_actions);
88            }
89        }
90
91        source
92    }
93
94    /// create a new data device for a given seat
95    pub fn get_data_device<D>(&self, qh: &QueueHandle<D>, seat: &WlSeat) -> DataDevice
96    where
97        D: Dispatch<wl_data_device::WlDataDevice, DataDeviceData> + 'static,
98    {
99        let data = DataDeviceData::new(seat.clone());
100        DataDevice { device: self.manager.get_data_device(seat, qh, data) }
101    }
102}
103
104impl ProvidesBoundGlobal<WlDataDeviceManager, 3> for DataDeviceManagerState {
105    fn bound_global(&self) -> Result<WlDataDeviceManager, GlobalError> {
106        Ok(self.manager.clone())
107    }
108}
109
110impl<D> Dispatch<wl_data_device_manager::WlDataDeviceManager, GlobalData, D>
111    for DataDeviceManagerState
112where
113    D: Dispatch<wl_data_device_manager::WlDataDeviceManager, GlobalData>,
114{
115    fn event(
116        _state: &mut D,
117        _proxy: &wl_data_device_manager::WlDataDeviceManager,
118        _event: <wl_data_device_manager::WlDataDeviceManager as wayland_client::Proxy>::Event,
119        _data: &GlobalData,
120        _conn: &Connection,
121        _qhandle: &QueueHandle<D>,
122    ) {
123        unreachable!("wl_data_device_manager has no events")
124    }
125}
126
127#[macro_export]
128macro_rules! delegate_data_device {
129    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
130        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
131            [
132                $crate::reexports::client::protocol::wl_data_device_manager::WlDataDeviceManager: $crate::globals::GlobalData
133            ] => $crate::data_device_manager::DataDeviceManagerState);
134        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
135            [
136                $crate::reexports::client::protocol::wl_data_offer::WlDataOffer: $crate::data_device_manager::data_offer::DataOfferData
137            ] => $crate::data_device_manager::DataDeviceManagerState);
138        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
139            [
140                $crate::reexports::client::protocol::wl_data_source::WlDataSource: $crate::data_device_manager::data_source::DataSourceData
141            ] => $crate::data_device_manager::DataDeviceManagerState
142        );
143        $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty:
144            [
145                $crate::reexports::client::protocol::wl_data_device::WlDataDevice: $crate::data_device_manager::data_device::DataDeviceData
146            ] => $crate::data_device_manager::DataDeviceManagerState
147        );
148    };
149}