smithay/wayland/selection/
mod.rs

1//! Handler utilities for the various selection protocols.
2//!
3//! Wayland originally only had a singe way to deal with the user clipboard with the help of
4//! `wl_data_device` protocol. However the demand for *primary* selection as well as writing
5//! clipboard managers made it into developing protocol extension for the said cases.
6//!
7//! The following selection providers are supported:
8//!
9//! - The [`data_device`](data_device/index.html) module to work with the traditional clipboard selection.
10//! - The [`primary_selection`](primary_selection/index.html) module to work with the primary selection.
11//! - The [`wlr_data_control`](wlr_data_control/index.html) module to hook data control into
12//!   clipboard and primary selection
13
14use std::os::unix::io::OwnedFd;
15
16use crate::input::{Seat, SeatHandler};
17
18pub mod data_device;
19pub mod ext_data_control;
20pub mod primary_selection;
21pub mod wlr_data_control;
22
23mod device;
24mod offer;
25mod seat_data;
26mod source;
27
28pub use source::SelectionSource;
29
30/// Events that are generated by interactions of the clients with the data device.
31pub trait SelectionHandler: Sized + SeatHandler {
32    /// UserData attached to server-side selections.
33    type SelectionUserData: Clone + Send + Sync + 'static;
34
35    /// A client has set the selection
36    #[allow(unused_variables)]
37    fn new_selection(&mut self, ty: SelectionTarget, source: Option<SelectionSource>, seat: Seat<Self>) {}
38
39    /// A client requested to read the server-set selection.
40    ///
41    /// * `mime_type` - the requested mime type
42    /// * `fd` - the fd to write into
43    #[allow(unused_variables)]
44    fn send_selection(
45        &mut self,
46        ty: SelectionTarget,
47        mime_type: String,
48        fd: OwnedFd,
49        seat: Seat<Self>,
50        user_data: &Self::SelectionUserData,
51    ) {
52    }
53}
54
55/// The target for the selection request.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum SelectionTarget {
58    /// The target for the request is primary selection.
59    Primary,
60    /// The target for the request is clipboard selection.
61    Clipboard,
62}
63
64pub(crate) mod private {
65    /// `selection_dispatch!(self; Enum(foo) => foo.something())`
66    /// expands to the equivalent of
67    /// ```ignore
68    /// match self {
69    ///    Enum::DataDevice(foo) => foo.something(),
70    ///    Enum::Primary(foo) => foo.something(),
71    ///    Enum::WlrDataControl(foo) => foo.something(),
72    ///    Enum::ExtDataControl(foo) => foo.something(),
73    /// }
74    /// ```
75    ///
76    /// And `selection_dispatch!(self, other; Enum(foo), EnumNext(zoo) => foo.something(zoo))` expands
77    /// to the equivalent of
78    /// ```ignore
79    /// match (self, other) {
80    ///    (Enum::DataDevice(foo), EnumNext::DataDevice(zoo))  => foo.something(zoo),
81    ///    (Enum::Primary(foo), EnumNext::Primary(zoo))  => foo.something(zoo),
82    ///    (Enum::WlrDataControl(foo), EnumNext::WlrDataControl(zoo))  => foo.something(zoo),
83    ///    (Enum::ExtDataControl(foo), EnumNext::ExtDataControl(zoo))  => foo.something(zoo),
84    ///    _ => unreachable!(),
85    /// }
86    /// ```
87    ///
88    /// The result can be converted to another enum by adding `; as AnotherEnum`
89    macro_rules! selection_dispatch {
90        ($what:ident; $enum:ident ( $($c1:tt)* ) => $x:expr) => {
91            match $what {
92                $enum::DataDevice($($c1)*) => $x,
93                $enum::Primary($($c1)*) => $x,
94                $enum::WlrDataControl($($c1)*) => $x,
95                $enum::ExtDataControl($($c1)*) => $x,
96            }
97        };
98        ($what:ident$(, $what_next:ident)+; $enum:ident ( $($c1:tt)*) $(, $enum_next:ident ( $($c2:tt)* ) )+ => $x:expr) => {
99            match ($what$(, $what_next)*) {
100                ($enum::DataDevice($($c1)*)$(, $enum_next::DataDevice($($c2)*))*) => $x,
101                ($enum::Primary($($c1)*)$(, $enum_next::Primary($($c2)*))*) => $x,
102                ($enum::WlrDataControl($($c1)*)$(, $enum_next::WlrDataControl($($c2)*))*) => $x,
103                ($enum::ExtDataControl($($c1)*)$(, $enum_next::ExtDataControl($($c2)*))*) => $x,
104                _ => unreachable!(),
105            }
106        };
107    }
108
109    pub(crate) use selection_dispatch;
110}