barust 0.3.0

A X11 status bar
Documentation
#![allow(non_snake_case)]

use crate::atoms;
use std::sync::OnceLock;
use xcb::Connection;

static ATOMS: OnceLock<Atoms> = OnceLock::new();

atoms!(
     struct Atoms {
        MANAGER,
        UTF8_STRING,
        _NET_ACTIVE_WINDOW,
        _NET_CURRENT_DESKTOP,
        _NET_DESKTOP_NAMES,
        _NET_SYSTEM_TRAY_OPCODE,
        _NET_SYSTEM_TRAY_ORIENTATION,
        _NET_SYSTEM_TRAY_S0,
        _NET_SYSTEM_TRAY_VISUAL,
        _NET_WM_NAME,
        _NET_WM_WINDOW_TYPE,
        _NET_WM_WINDOW_TYPE_DOCK,
        _XEMBED,
        _XEMBED_EMBEDDED_NOTIFY,
    }
);

#[macro_export]
macro_rules! atoms {
    (
        struct $Atoms:ident {
            $(
                $field:ident,
            )*
        }
    ) => {
        #[derive(Copy, Clone, Debug)]
        pub struct $Atoms {
            $(pub $field: xcb::x::Atom,)*
        }
        impl $Atoms {
            #[allow(dead_code)]
            fn intern_all(conn: &xcb::Connection) -> xcb::Result<$Atoms> {
                $(
                    let $field = conn.send_request(&xcb::x::InternAtom {
                        only_if_exists: false, // NOTE: this is important
                        name: stringify!($field).as_bytes(),
                    });
                )*
                Ok($Atoms {
                    $(
                        $field: conn.wait_for_reply($field)?.atom(),
                    )*
                })
            }
        }
    };
}

impl Atoms {
    pub fn new(connection: &Connection) -> xcb::Result<&'static Atoms> {
        if ATOMS.get().is_none() {
            let inner = Atoms::intern_all(connection)?;
            ATOMS.set(inner).unwrap();
        }
        Ok(ATOMS.get().unwrap())
    }
}