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}
150