x11rb

Macro atom_manager

Source
macro_rules! atom_manager {
    {
        $(#[$struct_meta:meta])*
        $vis:vis $struct_name:ident:
        $(#[$cookie_meta:meta])*
        $cookie_name:ident {
            $($field_name:ident$(: $atom_value:expr)?,)*
        }
    } => { ... };
}
Expand description

A helper macro for managing atoms

In X11, one often has to work with many different atoms that are already known at compile time. This macro can simplify managing such a list of atoms.

The following macro invocation:

atom_manager! {
    /// A collection of Atoms.
    pub AtomCollection:
    /// A handle to a response from the X11 server.
    AtomCollectionCookie {
        _NET_WM_NAME,
        _NET_WM_ICON,
        ATOM_WITH_SPACES: b"ATOM WITH SPACES",
        WHATEVER,
    }
}

…expands to this:

#[allow(non_snake_case)]
#[derive(Debug, Clone, Copy)]
/// A collection of Atoms.
pub struct AtomCollection {
    pub _NET_WM_NAME: Atom,
    pub _NET_WM_ICON: Atom,
    pub ATOM_WITH_SPACES: Atom,
    pub WHATEVER: Atom,
}

#[allow(non_snake_case)]
#[derive(Debug)]
/// A handle to a response from the X11 server.
struct AtomCollectionCookie<'c, C: ConnectionExt> {
    // please treat the actual members as private
}

impl AtomCollection {
    pub fn new<C: ConnectionExt>(
        conn: &C,
    ) -> Result<AtomCollectionCookie<'_, C>, ConnectionError> {
        // This is just an example for readability; the actual code is more efficient.
        Ok(AtomCollectionCookie {
            phantom: std::marker::PhantomData,
            _NET_WM_NAME: conn.intern_atom(false, b"_NET_WM_NAME")?,
            _NET_WM_ICON: conn.intern_atom(false, b"_NET_WM_ICON")?,
            ATOM_WITH_SPACES: conn.intern_atom(false, b"ATOM WITH SPACES")?,
            WHATEVER: conn.intern_atom(false, b"WHATEVER")?,
        })
    }
}

impl<'c, C> AtomCollectionCookie<'c, C>
where
    C: ConnectionExt,
{
    pub fn reply(self) -> Result<AtomCollection, ReplyError> {
        // This is just an example for readability; the actual code is different.
        Ok(AtomCollection {
            _NET_WM_NAME: self._NET_WM_NAME.reply()?.atom,
            _NET_WM_ICON: self._NET_WM_ICON.reply()?.atom,
            ATOM_WITH_SPACES: self.ATOM_WITH_SPACES.reply()?.atom,
            WHATEVER: self.WHATEVER.reply()?.atom,
        })
    }
}