x11-overlay 0.1.0

A library for creating overlay interfaces on X11 systems using Cairo for rendering
Documentation
use anyhow::Result;
use std::collections::HashMap;
use x11rb::connection::Connection;
use x11rb::protocol::xproto::*;

pub struct AtomCache {
    atoms: HashMap<String, Atom>,
}

impl AtomCache {
    pub fn new() -> Self {
        Self {
            atoms: HashMap::new(),
        }
    }

    pub fn get_atom<C: Connection>(&mut self, conn: &C, name: &str) -> Result<Atom> {
        if let Some(&atom) = self.atoms.get(name) {
            return Ok(atom);
        }

        let atom = conn.intern_atom(false, name.as_bytes())?.reply()?.atom;
        self.atoms.insert(name.to_string(), atom);
        Ok(atom)
    }

    pub fn get_atoms<C: Connection>(&mut self, conn: &C, names: &[&str]) -> Result<Vec<Atom>> {
        names.iter().map(|name| self.get_atom(conn, name)).collect()
    }
}

impl Default for AtomCache {
    fn default() -> Self {
        Self::new()
    }
}

pub struct CommonAtoms {
    pub wm_protocols: Atom,
    pub wm_delete_window: Atom,
    pub wm_state: Atom,
    pub wm_change_state: Atom,
    pub net_wm_state: Atom,
    pub net_wm_state_above: Atom,
    pub net_wm_state_below: Atom,
    pub net_wm_state_sticky: Atom,
    pub net_wm_state_skip_taskbar: Atom,
    pub net_wm_state_skip_pager: Atom,
    pub net_wm_window_type: Atom,
    pub net_wm_window_type_desktop: Atom,
    pub net_wm_window_type_dock: Atom,
    pub net_wm_window_type_toolbar: Atom,
    pub net_wm_window_type_utility: Atom,
    pub net_wm_window_type_dialog: Atom,
    pub net_wm_window_type_normal: Atom,
    pub net_wm_name: Atom,
    pub net_wm_visible_name: Atom,
    pub net_wm_desktop: Atom,
    pub net_current_desktop: Atom,
    pub net_number_of_desktops: Atom,
    pub net_supporting_wm_check: Atom,
    pub net_wm_pid: Atom,
    pub utf8_string: Atom,
}

impl CommonAtoms {
    pub fn new<C: Connection>(conn: &C) -> Result<Self> {
        let atom_names = [
            "WM_PROTOCOLS",
            "WM_DELETE_WINDOW",
            "WM_STATE",
            "WM_CHANGE_STATE",
            "_NET_WM_STATE",
            "_NET_WM_STATE_ABOVE",
            "_NET_WM_STATE_BELOW",
            "_NET_WM_STATE_STICKY",
            "_NET_WM_STATE_SKIP_TASKBAR",
            "_NET_WM_STATE_SKIP_PAGER",
            "_NET_WM_WINDOW_TYPE",
            "_NET_WM_WINDOW_TYPE_DESKTOP",
            "_NET_WM_WINDOW_TYPE_DOCK",
            "_NET_WM_WINDOW_TYPE_TOOLBAR",
            "_NET_WM_WINDOW_TYPE_UTILITY",
            "_NET_WM_WINDOW_TYPE_DIALOG",
            "_NET_WM_WINDOW_TYPE_NORMAL",
            "_NET_WM_NAME",
            "_NET_WM_VISIBLE_NAME",
            "_NET_WM_DESKTOP",
            "_NET_CURRENT_DESKTOP",
            "_NET_NUMBER_OF_DESKTOPS",
            "_NET_SUPPORTING_WM_CHECK",
            "_NET_WM_PID",
            "UTF8_STRING",
        ];

        let cookies: Result<Vec<_>, _> = atom_names
            .iter()
            .map(|name| conn.intern_atom(false, name.as_bytes()))
            .collect();

        let atoms: Vec<Atom> = cookies?
            .into_iter()
            .map(|cookie| cookie.reply().map(|reply| reply.atom))
            .collect::<Result<Vec<_>, _>>()?;

        Ok(Self {
            wm_protocols: atoms[0],
            wm_delete_window: atoms[1],
            wm_state: atoms[2],
            wm_change_state: atoms[3],
            net_wm_state: atoms[4],
            net_wm_state_above: atoms[5],
            net_wm_state_below: atoms[6],
            net_wm_state_sticky: atoms[7],
            net_wm_state_skip_taskbar: atoms[8],
            net_wm_state_skip_pager: atoms[9],
            net_wm_window_type: atoms[10],
            net_wm_window_type_desktop: atoms[11],
            net_wm_window_type_dock: atoms[12],
            net_wm_window_type_toolbar: atoms[13],
            net_wm_window_type_utility: atoms[14],
            net_wm_window_type_dialog: atoms[15],
            net_wm_window_type_normal: atoms[16],
            net_wm_name: atoms[17],
            net_wm_visible_name: atoms[18],
            net_wm_desktop: atoms[19],
            net_current_desktop: atoms[20],
            net_number_of_desktops: atoms[21],
            net_supporting_wm_check: atoms[22],
            net_wm_pid: atoms[23],
            utf8_string: atoms[24],
        })
    }
}