From be77aaf22bc0e392c19ebc7fc49cd636f6a14bce Mon Sep 17 00:00:00 2001 From: PolyMeilex Date: Thu, 24 Oct 2024 19:37:58 +0200 Subject: [PATCH] xdg_system_bell: Implement v1 of xdg system bell --- Cargo.toml | 2 +- src/wayland/mod.rs | 1 + src/wayland/xdg_system_bell.rs | 110 +++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/wayland/xdg_system_bell.rs diff --git a/Cargo.toml b/Cargo.toml index ffbc701b41dc..cdd844fb6820 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ udev = { version = "0.9.0", optional = true } wayland-client = { version = "0.31.3", optional = true } wayland-cursor = { version = "0.31.3", optional = true } wayland-egl = { version = "0.32.0", optional = true } -wayland-protocols = { version = "0.32.4", features = ["unstable", "staging", "server"], optional = true } +wayland-protocols = { version = "0.32.5", features = ["unstable", "staging", "server"], optional = true } wayland-protocols-wlr = { version = "0.3.1", features = ["server"], optional = true } wayland-protocols-misc = { version = "0.3.1", features = ["server"], optional = true } wayland-server = { version = "0.31.0", optional = true } diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index ecddf6588a50..8eda887be15e 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -80,6 +80,7 @@ pub mod viewporter; pub mod virtual_keyboard; pub mod xdg_activation; pub mod xdg_foreign; +pub mod xdg_system_bell; pub mod xdg_toplevel_icon; #[cfg(feature = "xwayland")] pub mod xwayland_keyboard_grab; diff --git a/src/wayland/xdg_system_bell.rs b/src/wayland/xdg_system_bell.rs new file mode 100644 index 000000000000..648fa2e467a6 --- /dev/null +++ b/src/wayland/xdg_system_bell.rs @@ -0,0 +1,110 @@ +//! XDG System Bell +//! +//! This protocol enables clients to ring the system bell. +//! +//! In order to advertise system bell global call [XdgSystemBellState::new] and delegate +//! events to it with [delegate_xdg_system_bell]. +//! +//! ``` +//! use smithay::wayland::xdg_system_bell::{XdgSystemBellState, XdgSystemBellHandler}; +//! use wayland_server::protocol::wl_surface::WlSurface; +//! use smithay::delegate_xdg_system_bell; +//! +//! # struct State; +//! # let mut display = wayland_server::Display::::new().unwrap(); +//! +//! XdgSystemBellState::new::( +//! &display.handle(), +//! ); +//! +//! // provide the necessary trait implementations +//! impl XdgSystemBellHandler for State { +//! fn ring(&mut self, surface: Option) { +//! println!("Ring got called"); +//! } +//! } +//! +//! delegate_xdg_system_bell!(State); +//! ``` + +use wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::{self, XdgSystemBellV1}; +use wayland_server::{ + backend::GlobalId, protocol::wl_surface::WlSurface, Client, DataInit, Dispatch, DisplayHandle, + GlobalDispatch, New, +}; + +/// Handler for xdg ring request +pub trait XdgSystemBellHandler: + GlobalDispatch + Dispatch + 'static +{ + /// Ring the system bell + fn ring(&mut self, surface: Option); +} + +/// State of the xdg system bell +#[derive(Debug)] +pub struct XdgSystemBellState { + global_id: GlobalId, +} + +impl XdgSystemBellState { + /// Register new [XdgSystemBellV1] global + pub fn new(display: &DisplayHandle) -> Self { + let global_id = display.create_global::(1, ()); + Self { global_id } + } + + /// [XdgSystemBellV1] GlobalId getter + pub fn global(&self) -> GlobalId { + self.global_id.clone() + } +} + +impl GlobalDispatch for XdgSystemBellState { + fn bind( + _state: &mut D, + _handle: &DisplayHandle, + _client: &Client, + resource: New, + _global_data: &(), + data_init: &mut DataInit<'_, D>, + ) { + data_init.init(resource, ()); + } +} + +impl Dispatch for XdgSystemBellState { + fn request( + state: &mut D, + _client: &wayland_server::Client, + _resource: &XdgSystemBellV1, + request: xdg_system_bell_v1::Request, + _data: &(), + _dhandle: &DisplayHandle, + _data_init: &mut DataInit<'_, D>, + ) { + match request { + xdg_system_bell_v1::Request::Ring { surface } => { + state.ring(surface); + } + xdg_system_bell_v1::Request::Destroy => {} + _ => unreachable!(), + } + } +} + +/// Macro to delegate implementation of the xdg system bell to [`XdgSystemBellState`]. +/// +/// You must also implement [`XdgSystemBellHandler`] to use this. +#[macro_export] +macro_rules! delegate_xdg_system_bell { + ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { + $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + $crate::reexports::wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::XdgSystemBellV1: () + ] => $crate::wayland::xdg_system_bell::XdgSystemBellState); + + $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + $crate::reexports::wayland_protocols::xdg::system_bell::v1::server::xdg_system_bell_v1::XdgSystemBellV1: () + ] => $crate::wayland::xdg_system_bell::XdgSystemBellState); + }; +}