smithay_client_toolkit/data_device_manager/
data_source.rs1use crate::dispatch2::Dispatch2;
2use crate::reexports::client::{
3 protocol::{
4 wl_data_device_manager::DndAction,
5 wl_data_source::{self, WlDataSource},
6 wl_surface::WlSurface,
7 },
8 Connection, Proxy, QueueHandle, WEnum,
9};
10
11use super::{data_device::DataDevice, WritePipe};
12
13#[derive(Debug, Default)]
14pub struct DataSourceData<U> {
15 udata: U,
16}
17
18impl<U> DataSourceData<U> {
19 pub fn new(udata: U) -> Self {
20 Self { udata }
21 }
22
23 pub fn data(&self) -> &U {
24 &self.udata
25 }
26
27 pub fn data_mut(&mut self) -> &mut U {
28 &mut self.udata
29 }
30}
31
32pub trait DataSourceHandler: Sized {
36 fn accept_mime(
38 &mut self,
39 conn: &Connection,
40 qh: &QueueHandle<Self>,
41 source: &WlDataSource,
42 mime: Option<String>,
43 );
44
45 fn send_request(
48 &mut self,
49 conn: &Connection,
50 qh: &QueueHandle<Self>,
51 source: &WlDataSource,
52 mime: String,
53 fd: WritePipe,
54 );
55
56 fn cancelled(&mut self, conn: &Connection, qh: &QueueHandle<Self>, source: &WlDataSource);
59
60 fn dnd_dropped(&mut self, conn: &Connection, qh: &QueueHandle<Self>, source: &WlDataSource);
63
64 fn dnd_finished(&mut self, conn: &Connection, qh: &QueueHandle<Self>, source: &WlDataSource);
67
68 fn action(
70 &mut self,
71 conn: &Connection,
72 qh: &QueueHandle<Self>,
73 source: &WlDataSource,
74 action: DndAction,
75 );
76}
77
78impl<D, U> Dispatch2<wl_data_source::WlDataSource, D> for DataSourceData<U>
79where
80 D: DataSourceHandler,
81{
82 fn event(
83 &self,
84 state: &mut D,
85 source: &wl_data_source::WlDataSource,
86 event: <wl_data_source::WlDataSource as wayland_client::Proxy>::Event,
87 conn: &wayland_client::Connection,
88 qh: &wayland_client::QueueHandle<D>,
89 ) {
90 match event {
91 wl_data_source::Event::Target { mime_type } => {
92 state.accept_mime(conn, qh, source, mime_type)
93 }
94 wl_data_source::Event::Send { mime_type, fd } => {
95 state.send_request(conn, qh, source, mime_type, fd.into());
96 }
97 wl_data_source::Event::Cancelled => {
98 state.cancelled(conn, qh, source);
99 }
100 wl_data_source::Event::DndDropPerformed => {
101 state.dnd_dropped(conn, qh, source);
102 }
103 wl_data_source::Event::DndFinished => {
104 state.dnd_finished(conn, qh, source);
105 }
106 wl_data_source::Event::Action { dnd_action } => match dnd_action {
107 WEnum::Value(dnd_action) => {
108 state.action(conn, qh, source, dnd_action);
109 }
110 WEnum::Unknown(_) => {}
111 },
112 _ => unimplemented!(),
113 };
114 }
115}
116
117#[derive(Debug, PartialEq, Eq, Clone)]
118pub struct CopyPasteSource {
119 pub(crate) inner: WlDataSource,
120}
121
122impl CopyPasteSource {
123 pub fn set_selection(&self, device: &DataDevice, serial: u32) {
125 device.device.set_selection(Some(&self.inner), serial);
126 }
127
128 pub fn inner(&self) -> &WlDataSource {
129 &self.inner
130 }
131}
132
133impl Drop for CopyPasteSource {
134 fn drop(&mut self) {
135 self.inner.destroy();
136 }
137}
138
139#[derive(Debug, PartialEq, Eq, Clone)]
140pub struct DragSource {
141 pub(crate) inner: WlDataSource,
142}
143
144impl DragSource {
145 pub fn start_drag(
149 &self,
150 device: &DataDevice,
151 origin: &WlSurface,
152 icon: Option<&WlSurface>,
153 serial: u32,
154 ) {
155 device.device.start_drag(Some(&self.inner), origin, icon, serial);
156 }
157
158 pub fn start_internal_drag(
162 device: &DataDevice,
163 origin: &WlSurface,
164 icon: Option<&WlSurface>,
165 serial: u32,
166 ) {
167 device.device.start_drag(None, origin, icon, serial);
168 }
169
170 pub fn set_actions(&self, dnd_actions: DndAction) {
173 if self.inner.version() >= 3 {
174 self.inner.set_actions(dnd_actions);
175 }
176 self.inner.set_actions(dnd_actions);
177 }
178
179 pub fn inner(&self) -> &WlDataSource {
181 &self.inner
182 }
183}
184
185impl Drop for DragSource {
186 fn drop(&mut self) {
187 self.inner.destroy();
188 }
189}