simple_window/common/protocols_data/wayland/
wl_data_source.rs

1//! offer to transfer data
2//!
3//! The wl_data_source object is the source side of a wl_data_offer.
4//! It is created by the source client in a data transfer and
5//! provides a way to describe the offered data and a way to respond
6//! to requests to transfer the data.
7
8use {super::super::all_types::*, ::wl_client::builder::prelude::*};
9
10static INTERFACE: wl_interface = wl_interface {
11    name: c"wl_data_source".as_ptr(),
12    version: 3,
13    method_count: 3,
14    methods: {
15        static MESSAGES: [wl_message; 3] = [
16            wl_message {
17                name: c"offer".as_ptr(),
18                signature: c"s".as_ptr(),
19                types: {
20                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
21                    TYPES.as_ptr().cast()
22                },
23            },
24            wl_message {
25                name: c"destroy".as_ptr(),
26                signature: c"".as_ptr(),
27                types: {
28                    static TYPES: [Option<&'static wl_interface>; 0] = [];
29                    TYPES.as_ptr().cast()
30                },
31            },
32            wl_message {
33                name: c"set_actions".as_ptr(),
34                signature: c"u".as_ptr(),
35                types: {
36                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
37                    TYPES.as_ptr().cast()
38                },
39            },
40        ];
41        MESSAGES.as_ptr()
42    },
43    event_count: 6,
44    events: {
45        static MESSAGES: [wl_message; 6] = [
46            wl_message {
47                name: c"target".as_ptr(),
48                signature: c"?s".as_ptr(),
49                types: {
50                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
51                    TYPES.as_ptr().cast()
52                },
53            },
54            wl_message {
55                name: c"send".as_ptr(),
56                signature: c"sh".as_ptr(),
57                types: {
58                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
59                    TYPES.as_ptr().cast()
60                },
61            },
62            wl_message {
63                name: c"cancelled".as_ptr(),
64                signature: c"".as_ptr(),
65                types: {
66                    static TYPES: [Option<&'static wl_interface>; 0] = [];
67                    TYPES.as_ptr().cast()
68                },
69            },
70            wl_message {
71                name: c"dnd_drop_performed".as_ptr(),
72                signature: c"".as_ptr(),
73                types: {
74                    static TYPES: [Option<&'static wl_interface>; 0] = [];
75                    TYPES.as_ptr().cast()
76                },
77            },
78            wl_message {
79                name: c"dnd_finished".as_ptr(),
80                signature: c"".as_ptr(),
81                types: {
82                    static TYPES: [Option<&'static wl_interface>; 0] = [];
83                    TYPES.as_ptr().cast()
84                },
85            },
86            wl_message {
87                name: c"action".as_ptr(),
88                signature: c"u".as_ptr(),
89                types: {
90                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
91                    TYPES.as_ptr().cast()
92                },
93            },
94        ];
95        MESSAGES.as_ptr()
96    },
97};
98
99/// An owned wl_data_source proxy.
100///
101/// See the documentation of [the module][self] for the interface description.
102#[derive(Clone, Eq, PartialEq)]
103#[repr(transparent)]
104pub struct WlDataSource {
105    /// This proxy has the interface INTERFACE.
106    proxy: UntypedOwnedProxy,
107}
108
109/// A borrowed wl_data_source proxy.
110///
111/// See the documentation of [the module][self] for the interface description.
112#[derive(Eq, PartialEq)]
113#[repr(transparent)]
114pub struct WlDataSourceRef {
115    /// This proxy has the interface INTERFACE.
116    proxy: UntypedBorrowedProxy,
117}
118
119// SAFETY: WlDataSource is a transparent wrapper around UntypedOwnedProxy
120unsafe impl UntypedOwnedProxyWrapper for WlDataSource {}
121
122// SAFETY: - INTERFACE is a valid wl_interface
123//         - The only invariant is that self.proxy has a compatible interface
124unsafe impl OwnedProxy for WlDataSource {
125    const INTERFACE: &'static str = "wl_data_source";
126    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
127    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
128        private::EventHandler(private::NoOpEventHandler);
129    const MAX_VERSION: u32 = 3;
130
131    type Borrowed = WlDataSourceRef;
132    type Api = private::ProxyApi;
133    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
134}
135
136// SAFETY: WlDataSourceRef is a transparent wrapper around UntypedBorrowedProxy
137unsafe impl UntypedBorrowedProxyWrapper for WlDataSourceRef {}
138
139// SAFETY: - The only invariant is that self.proxy has a compatible interface
140unsafe impl BorrowedProxy for WlDataSourceRef {
141    type Owned = WlDataSource;
142}
143
144impl Deref for WlDataSource {
145    type Target = WlDataSourceRef;
146
147    fn deref(&self) -> &Self::Target {
148        proxy::low_level::deref(self)
149    }
150}
151
152mod private {
153    pub struct ProxyApi;
154
155    #[allow(dead_code)]
156    pub struct EventHandler<H>(pub(super) H);
157
158    #[allow(dead_code)]
159    pub struct NoOpEventHandler;
160}
161
162impl Debug for WlDataSource {
163    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
164        write!(f, "wl_data_source#{}", self.proxy.id())
165    }
166}
167
168impl Debug for WlDataSourceRef {
169    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
170        write!(f, "wl_data_source#{}", self.proxy.id())
171    }
172}
173
174impl PartialEq<WlDataSourceRef> for WlDataSource {
175    fn eq(&self, other: &WlDataSourceRef) -> bool {
176        self.proxy == other.proxy
177    }
178}
179
180impl PartialEq<WlDataSource> for WlDataSourceRef {
181    fn eq(&self, other: &WlDataSource) -> bool {
182        self.proxy == other.proxy
183    }
184}
185
186#[allow(dead_code)]
187impl WlDataSource {
188    /// Since when the destroy request is available.
189    #[allow(dead_code)]
190    pub const REQ__DESTROY__SINCE: u32 = 1;
191
192    /// destroy the data source
193    ///
194    /// Destroy the data source.
195    #[inline]
196    pub fn destroy(&self) {
197        let mut args = [];
198        // SAFETY: - self.proxy has the interface INTERFACE
199        //         - 1 < INTERFACE.method_count = 3
200        //         - the request signature is ``
201        unsafe {
202            self.proxy.send_destructor(1, &mut args);
203        }
204    }
205}
206
207#[allow(dead_code)]
208impl WlDataSourceRef {
209    /// add an offered mime type
210    ///
211    /// This request adds a mime type to the set of mime types
212    /// advertised to targets.  Can be called several times to offer
213    /// multiple types.
214    ///
215    /// # Arguments
216    ///
217    /// - `mime_type`: mime type offered by the data source
218    #[inline]
219    pub fn offer(&self, mime_type: &str) {
220        let (arg0,) = (mime_type,);
221        with_cstr_cache(|cache| {
222            let str0_offset = cache.len();
223            cache.extend_from_slice(arg0.as_bytes());
224            cache.push(0);
225            let str0 = cache[str0_offset..].as_ptr().cast();
226            let mut args = [wl_argument { s: str0 }];
227            // SAFETY: - self.proxy has the interface INTERFACE
228            //         - 0 < INTERFACE.method_count = 3
229            //         - the request signature is `s`
230            unsafe {
231                self.proxy.send_request(0, &mut args);
232            }
233        })
234    }
235
236    /// set the available drag-and-drop actions
237    ///
238    /// Sets the actions that the source side client supports for this
239    /// operation. This request may trigger wl_data_source.action and
240    /// wl_data_offer.action events if the compositor needs to change the
241    /// selected action.
242    ///
243    /// The dnd_actions argument must contain only values expressed in the
244    /// wl_data_device_manager.dnd_actions enum, otherwise it will result
245    /// in a protocol error.
246    ///
247    /// This request must be made once only, and can only be made on sources
248    /// used in drag-and-drop, so it must be performed before
249    /// wl_data_device.start_drag. Attempting to use the source other than
250    /// for drag-and-drop will raise a protocol error.
251    ///
252    /// # Arguments
253    ///
254    /// - `dnd_actions`: actions supported by the data source
255    #[inline]
256    pub fn set_actions(&self, dnd_actions: WlDataDeviceManagerDndAction) {
257        let (arg0,) = (dnd_actions,);
258        let mut args = [wl_argument { u: arg0.0 }];
259        // SAFETY: - self.proxy has the interface INTERFACE
260        //         - 2 < INTERFACE.method_count = 3
261        //         - the request signature is `u`
262        unsafe {
263            self.proxy.send_request(2, &mut args);
264        }
265    }
266}
267
268impl WlDataSource {
269    /// Since when the target event is available.
270    #[allow(dead_code)]
271    pub const EVT__TARGET__SINCE: u32 = 1;
272
273    /// Since when the send event is available.
274    #[allow(dead_code)]
275    pub const EVT__SEND__SINCE: u32 = 1;
276
277    /// Since when the cancelled event is available.
278    #[allow(dead_code)]
279    pub const EVT__CANCELLED__SINCE: u32 = 1;
280
281    /// Since when the dnd_drop_performed event is available.
282    #[allow(dead_code)]
283    pub const EVT__DND_DROP_PERFORMED__SINCE: u32 = 3;
284
285    /// Since when the dnd_finished event is available.
286    #[allow(dead_code)]
287    pub const EVT__DND_FINISHED__SINCE: u32 = 3;
288
289    /// Since when the action event is available.
290    #[allow(dead_code)]
291    pub const EVT__ACTION__SINCE: u32 = 3;
292}
293
294/// An event handler for [WlDataSource] proxies.
295#[allow(dead_code)]
296pub trait WlDataSourceEventHandler {
297    type Data: 'static;
298
299    /// a target accepts an offered mime type
300    ///
301    /// Sent when a target accepts pointer_focus or motion events.  If
302    /// a target does not accept any of the offered types, type is NULL.
303    ///
304    /// Used for feedback during drag-and-drop.
305    ///
306    /// # Arguments
307    ///
308    /// - `mime_type`: mime type accepted by the target
309    #[inline]
310    fn target(&self, _data: &mut Self::Data, _slf: &WlDataSourceRef, mime_type: Option<&str>) {
311        let _ = mime_type;
312    }
313
314    /// send the data
315    ///
316    /// Request for data from the client.  Send the data as the
317    /// specified mime type over the passed file descriptor, then
318    /// close it.
319    ///
320    /// # Arguments
321    ///
322    /// - `mime_type`: mime type for the data
323    /// - `fd`: file descriptor for the data
324    #[inline]
325    fn send(&self, _data: &mut Self::Data, _slf: &WlDataSourceRef, mime_type: &str, fd: OwnedFd) {
326        let _ = mime_type;
327        let _ = fd;
328    }
329
330    /// selection was cancelled
331    ///
332    /// This data source is no longer valid. There are several reasons why
333    /// this could happen:
334    ///
335    /// - The data source has been replaced by another data source.
336    /// - The drag-and-drop operation was performed, but the drop destination
337    ///   did not accept any of the mime types offered through
338    ///   wl_data_source.target.
339    /// - The drag-and-drop operation was performed, but the drop destination
340    ///   did not select any of the actions present in the mask offered through
341    ///   wl_data_source.action.
342    /// - The drag-and-drop operation was performed but didn't happen over a
343    ///   surface.
344    /// - The compositor cancelled the drag-and-drop operation (e.g. compositor
345    ///   dependent timeouts to avoid stale drag-and-drop transfers).
346    ///
347    /// The client should clean up and destroy this data source.
348    ///
349    /// For objects of version 2 or older, wl_data_source.cancelled will
350    /// only be emitted if the data source was replaced by another data
351    /// source.
352    #[inline]
353    fn cancelled(&self, _data: &mut Self::Data, _slf: &WlDataSourceRef) {}
354
355    /// the drag-and-drop operation physically finished
356    ///
357    /// The user performed the drop action. This event does not indicate
358    /// acceptance, wl_data_source.cancelled may still be emitted afterwards
359    /// if the drop destination does not accept any mime type.
360    ///
361    /// However, this event might however not be received if the compositor
362    /// cancelled the drag-and-drop operation before this event could happen.
363    ///
364    /// Note that the data_source may still be used in the future and should
365    /// not be destroyed here.
366    #[inline]
367    fn dnd_drop_performed(&self, _data: &mut Self::Data, _slf: &WlDataSourceRef) {}
368
369    /// the drag-and-drop operation concluded
370    ///
371    /// The drop destination finished interoperating with this data
372    /// source, so the client is now free to destroy this data source and
373    /// free all associated data.
374    ///
375    /// If the action used to perform the operation was "move", the
376    /// source can now delete the transferred data.
377    #[inline]
378    fn dnd_finished(&self, _data: &mut Self::Data, _slf: &WlDataSourceRef) {}
379
380    /// notify the selected action
381    ///
382    /// This event indicates the action selected by the compositor after
383    /// matching the source/destination side actions. Only one action (or
384    /// none) will be offered here.
385    ///
386    /// This event can be emitted multiple times during the drag-and-drop
387    /// operation, mainly in response to destination side changes through
388    /// wl_data_offer.set_actions, and as the data device enters/leaves
389    /// surfaces.
390    ///
391    /// It is only possible to receive this event after
392    /// wl_data_source.dnd_drop_performed if the drag-and-drop operation
393    /// ended in an "ask" action, in which case the final wl_data_source.action
394    /// event will happen immediately before wl_data_source.dnd_finished.
395    ///
396    /// Compositors may also change the selected action on the fly, mainly
397    /// in response to keyboard modifier changes during the drag-and-drop
398    /// operation.
399    ///
400    /// The most recent action received is always the valid one. The chosen
401    /// action may change alongside negotiation (e.g. an "ask" action can turn
402    /// into a "move" operation), so the effects of the final action must
403    /// always be applied in wl_data_offer.dnd_finished.
404    ///
405    /// Clients can trigger cursor surface changes from this point, so
406    /// they reflect the current action.
407    ///
408    /// # Arguments
409    ///
410    /// - `dnd_action`: action selected by the compositor
411    #[inline]
412    fn action(
413        &self,
414        _data: &mut Self::Data,
415        _slf: &WlDataSourceRef,
416        dnd_action: WlDataDeviceManagerDndAction,
417    ) {
418        let _ = dnd_action;
419    }
420}
421
422impl WlDataSourceEventHandler for private::NoOpEventHandler {
423    type Data = ();
424}
425
426// SAFETY: - INTERFACE is a valid wl_interface
427//         - mutable_type always returns the same value
428unsafe impl<H> EventHandler for private::EventHandler<H>
429where
430    H: WlDataSourceEventHandler,
431{
432    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
433
434    #[inline]
435    fn mutable_type() -> Option<(TypeId, &'static str)> {
436        let id = TypeId::of::<H::Data>();
437        let name = std::any::type_name::<H::Data>();
438        Some((id, name))
439    }
440
441    #[allow(unused_variables)]
442    unsafe fn handle_event(
443        &self,
444        queue: &Queue,
445        data: *mut u8,
446        slf: &UntypedBorrowedProxy,
447        opcode: u32,
448        args: *mut wl_argument,
449    ) {
450        // SAFETY: This function requires that slf has the interface INTERFACE
451        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDataSourceRef>(slf) };
452        // SAFETY: This function requires that data is `&mut T` where `T`
453        //         has the type id returned by `Self::mutable_type`, i.e.,
454        //         `T = H::Data`.
455        let data: &mut H::Data = unsafe { &mut *data.cast() };
456        match opcode {
457            0 => {
458                // SAFETY: INTERFACE requires that there are 1 arguments
459                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
460                // SAFETY: - INTERFACE requires that args[0] contains a string
461                //         - if the pointer is not null, then it is a c string
462                let arg0 = unsafe {
463                    convert_optional_string_arg("wl_data_source", "mime_type", args[0].s)
464                };
465                self.0.target(data, slf, arg0);
466            }
467            1 => {
468                // SAFETY: INTERFACE requires that there are 2 arguments
469                let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
470                // SAFETY: - INTERFACE requires that args[0] contains a string
471                //         - if the pointer is not null, then it is a c string
472                let arg0 = unsafe { convert_string_arg("wl_data_source", "mime_type", args[0].s) };
473                // SAFETY: - INTERFACE requires that args[1] contains a file descriptor
474                let arg1 = unsafe { OwnedFd::from_raw_fd(args[1].h) };
475                self.0.send(data, slf, arg0, arg1);
476            }
477            2 => {
478                self.0.cancelled(data, slf);
479            }
480            3 => {
481                self.0.dnd_drop_performed(data, slf);
482            }
483            4 => {
484                self.0.dnd_finished(data, slf);
485            }
486            5 => {
487                // SAFETY: INTERFACE requires that there are 1 arguments
488                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
489                // SAFETY: - INTERFACE requires that args[0] contains a uint
490                let arg0 = unsafe { WlDataDeviceManagerDndAction(args[0].u) };
491                self.0.action(data, slf, arg0);
492            }
493            _ => {
494                invalid_opcode("wl_data_source", opcode);
495            }
496        }
497    }
498}
499
500impl<H> CreateEventHandler<H> for private::ProxyApi
501where
502    H: WlDataSourceEventHandler,
503{
504    type EventHandler = private::EventHandler<H>;
505
506    #[inline]
507    fn create_event_handler(handler: H) -> Self::EventHandler {
508        private::EventHandler(handler)
509    }
510}
511
512impl WlDataSource {
513    /// Since when the error.invalid_action_mask enum variant is available.
514    #[allow(dead_code)]
515    pub const ENM__ERROR_INVALID_ACTION_MASK__SINCE: u32 = 1;
516    /// Since when the error.invalid_source enum variant is available.
517    #[allow(dead_code)]
518    pub const ENM__ERROR_INVALID_SOURCE__SINCE: u32 = 1;
519}
520
521#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
522#[allow(dead_code)]
523pub struct WlDataSourceError(pub u32);
524
525impl WlDataSourceError {
526    /// action mask contains invalid values
527    #[allow(dead_code)]
528    pub const INVALID_ACTION_MASK: Self = Self(0);
529
530    /// source doesn't accept this request
531    #[allow(dead_code)]
532    pub const INVALID_SOURCE: Self = Self(1);
533}
534
535impl Debug for WlDataSourceError {
536    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
537        let name = match *self {
538            Self::INVALID_ACTION_MASK => "INVALID_ACTION_MASK",
539            Self::INVALID_SOURCE => "INVALID_SOURCE",
540            _ => return Debug::fmt(&self.0, f),
541        };
542        f.write_str(name)
543    }
544}
545
546/// Functional event handlers.
547pub mod event_handlers {
548    use super::*;
549
550    /// Event handler for target events.
551    pub struct Target<T, F>(F, PhantomData<fn(&mut T)>);
552    impl<T, F> WlDataSourceEventHandler for Target<T, F>
553    where
554        T: 'static,
555        F: Fn(&mut T, &WlDataSourceRef, Option<&str>),
556    {
557        type Data = T;
558
559        #[inline]
560        fn target(&self, _data: &mut T, _slf: &WlDataSourceRef, mime_type: Option<&str>) {
561            self.0(_data, _slf, mime_type)
562        }
563    }
564
565    /// Event handler for send events.
566    pub struct Send<T, F>(F, PhantomData<fn(&mut T)>);
567    impl<T, F> WlDataSourceEventHandler for Send<T, F>
568    where
569        T: 'static,
570        F: Fn(&mut T, &WlDataSourceRef, &str, OwnedFd),
571    {
572        type Data = T;
573
574        #[inline]
575        fn send(&self, _data: &mut T, _slf: &WlDataSourceRef, mime_type: &str, fd: OwnedFd) {
576            self.0(_data, _slf, mime_type, fd)
577        }
578    }
579
580    /// Event handler for cancelled events.
581    pub struct Cancelled<T, F>(F, PhantomData<fn(&mut T)>);
582    impl<T, F> WlDataSourceEventHandler for Cancelled<T, F>
583    where
584        T: 'static,
585        F: Fn(&mut T, &WlDataSourceRef),
586    {
587        type Data = T;
588
589        #[inline]
590        fn cancelled(&self, _data: &mut T, _slf: &WlDataSourceRef) {
591            self.0(_data, _slf)
592        }
593    }
594
595    /// Event handler for dnd_drop_performed events.
596    pub struct DndDropPerformed<T, F>(F, PhantomData<fn(&mut T)>);
597    impl<T, F> WlDataSourceEventHandler for DndDropPerformed<T, F>
598    where
599        T: 'static,
600        F: Fn(&mut T, &WlDataSourceRef),
601    {
602        type Data = T;
603
604        #[inline]
605        fn dnd_drop_performed(&self, _data: &mut T, _slf: &WlDataSourceRef) {
606            self.0(_data, _slf)
607        }
608    }
609
610    /// Event handler for dnd_finished events.
611    pub struct DndFinished<T, F>(F, PhantomData<fn(&mut T)>);
612    impl<T, F> WlDataSourceEventHandler for DndFinished<T, F>
613    where
614        T: 'static,
615        F: Fn(&mut T, &WlDataSourceRef),
616    {
617        type Data = T;
618
619        #[inline]
620        fn dnd_finished(&self, _data: &mut T, _slf: &WlDataSourceRef) {
621            self.0(_data, _slf)
622        }
623    }
624
625    /// Event handler for action events.
626    pub struct Action<T, F>(F, PhantomData<fn(&mut T)>);
627    impl<T, F> WlDataSourceEventHandler for Action<T, F>
628    where
629        T: 'static,
630        F: Fn(&mut T, &WlDataSourceRef, WlDataDeviceManagerDndAction),
631    {
632        type Data = T;
633
634        #[inline]
635        fn action(
636            &self,
637            _data: &mut T,
638            _slf: &WlDataSourceRef,
639            dnd_action: WlDataDeviceManagerDndAction,
640        ) {
641            self.0(_data, _slf, dnd_action)
642        }
643    }
644
645    impl WlDataSource {
646        /// Creates an event handler for target events.
647        ///
648        /// The event handler ignores all other events.
649        #[allow(dead_code)]
650        pub fn on_target<T, F>(f: F) -> Target<T, F>
651        where
652            T: 'static,
653            F: Fn(&mut T, &WlDataSourceRef, Option<&str>),
654        {
655            Target(f, PhantomData)
656        }
657
658        /// Creates an event handler for send events.
659        ///
660        /// The event handler ignores all other events.
661        #[allow(dead_code)]
662        pub fn on_send<T, F>(f: F) -> Send<T, F>
663        where
664            T: 'static,
665            F: Fn(&mut T, &WlDataSourceRef, &str, OwnedFd),
666        {
667            Send(f, PhantomData)
668        }
669
670        /// Creates an event handler for cancelled events.
671        ///
672        /// The event handler ignores all other events.
673        #[allow(dead_code)]
674        pub fn on_cancelled<T, F>(f: F) -> Cancelled<T, F>
675        where
676            T: 'static,
677            F: Fn(&mut T, &WlDataSourceRef),
678        {
679            Cancelled(f, PhantomData)
680        }
681
682        /// Creates an event handler for dnd_drop_performed events.
683        ///
684        /// The event handler ignores all other events.
685        #[allow(dead_code)]
686        pub fn on_dnd_drop_performed<T, F>(f: F) -> DndDropPerformed<T, F>
687        where
688            T: 'static,
689            F: Fn(&mut T, &WlDataSourceRef),
690        {
691            DndDropPerformed(f, PhantomData)
692        }
693
694        /// Creates an event handler for dnd_finished events.
695        ///
696        /// The event handler ignores all other events.
697        #[allow(dead_code)]
698        pub fn on_dnd_finished<T, F>(f: F) -> DndFinished<T, F>
699        where
700            T: 'static,
701            F: Fn(&mut T, &WlDataSourceRef),
702        {
703            DndFinished(f, PhantomData)
704        }
705
706        /// Creates an event handler for action events.
707        ///
708        /// The event handler ignores all other events.
709        #[allow(dead_code)]
710        pub fn on_action<T, F>(f: F) -> Action<T, F>
711        where
712            T: 'static,
713            F: Fn(&mut T, &WlDataSourceRef, WlDataDeviceManagerDndAction),
714        {
715            Action(f, PhantomData)
716        }
717    }
718}