Skip to main content

smithay_client_toolkit/data_device_manager/
mod.rs

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