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}