smithay/wayland/
xdg_system_bell.rs

1//! XDG System Bell
2//!
3//! This protocol enables clients to ring the system bell.
4//!
5//! In order to advertise system bell global call [`XdgSystemBellState::new`] and delegate
6//! events to it with [`delegate_xdg_system_bell`][crate::delegate_xdg_system_bell].
7//!
8//! ```
9//! use smithay::wayland::xdg_system_bell::{XdgSystemBellState, XdgSystemBellHandler};
10//! use wayland_server::protocol::wl_surface::WlSurface;
11//! use smithay::delegate_xdg_system_bell;
12//!
13//! # struct State;
14//! # let mut display = wayland_server::Display::<State>::new().unwrap();
15//!
16//! XdgSystemBellState::new::<State>(
17//!     &display.handle(),
18//! );
19//!
20//! // provide the necessary trait implementations
21//! impl XdgSystemBellHandler for State {
22//!     fn ring(&mut self, surface: Option<WlSurface>) {
23//!         println!("Ring got called");
24//!     }
25//! }
26//!
27//! delegate_xdg_system_bell!(State);
28//! ```
29
30use wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::{self, XdgSystemBellV1};
31use wayland_server::{
32    backend::GlobalId, protocol::wl_surface::WlSurface, Client, DataInit, Dispatch, DisplayHandle,
33    GlobalDispatch, New,
34};
35
36/// Handler for xdg ring request
37pub trait XdgSystemBellHandler:
38    GlobalDispatch<XdgSystemBellV1, ()> + Dispatch<XdgSystemBellV1, ()> + 'static
39{
40    /// Ring the system bell
41    fn ring(&mut self, surface: Option<WlSurface>);
42}
43
44/// State of the xdg system bell
45#[derive(Debug)]
46pub struct XdgSystemBellState {
47    global_id: GlobalId,
48}
49
50impl XdgSystemBellState {
51    /// Register new [XdgSystemBellV1] global
52    pub fn new<D: XdgSystemBellHandler>(display: &DisplayHandle) -> Self {
53        let global_id = display.create_global::<D, XdgSystemBellV1, ()>(1, ());
54        Self { global_id }
55    }
56
57    /// [XdgSystemBellV1] GlobalId getter
58    pub fn global(&self) -> GlobalId {
59        self.global_id.clone()
60    }
61}
62
63impl<D: XdgSystemBellHandler> GlobalDispatch<XdgSystemBellV1, (), D> for XdgSystemBellState {
64    fn bind(
65        _state: &mut D,
66        _handle: &DisplayHandle,
67        _client: &Client,
68        resource: New<XdgSystemBellV1>,
69        _global_data: &(),
70        data_init: &mut DataInit<'_, D>,
71    ) {
72        data_init.init(resource, ());
73    }
74}
75
76impl<D: XdgSystemBellHandler> Dispatch<XdgSystemBellV1, (), D> for XdgSystemBellState {
77    fn request(
78        state: &mut D,
79        _client: &wayland_server::Client,
80        _resource: &XdgSystemBellV1,
81        request: xdg_system_bell_v1::Request,
82        _data: &(),
83        _dhandle: &DisplayHandle,
84        _data_init: &mut DataInit<'_, D>,
85    ) {
86        match request {
87            xdg_system_bell_v1::Request::Ring { surface } => {
88                state.ring(surface);
89            }
90            xdg_system_bell_v1::Request::Destroy => {}
91            _ => unreachable!(),
92        }
93    }
94}
95
96/// Macro to delegate implementation of the xdg system bell to [`XdgSystemBellState`].
97///
98/// You must also implement [`XdgSystemBellHandler`] to use this.
99#[macro_export]
100macro_rules! delegate_xdg_system_bell {
101    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
102        $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
103            $crate::reexports::wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::XdgSystemBellV1: ()
104        ] => $crate::wayland::xdg_system_bell::XdgSystemBellState);
105
106        $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
107            $crate::reexports::wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::XdgSystemBellV1: ()
108        ] => $crate::wayland::xdg_system_bell::XdgSystemBellState);
109    };
110}