Browse Source

Implement atom cache

Thomas Dy 8 years ago
parent
commit
44d1c7e365
2 changed files with 49 additions and 0 deletions
  1. 40 0
      src/atom.rs
  2. 9 0
      src/main.rs

+ 40 - 0
src/atom.rs

@@ -0,0 +1,40 @@
+use std::collections::HashMap;
+use std::cell::RefCell;
+use xcb;
+
+macro_rules! atoms {
+    ( $( $x:ident ),* ) => {
+        #[allow(non_snake_case)]
+        $(pub const $x: &'static str = stringify!($x);)*
+    }
+}
+
+atoms!(
+    _NET_SYSTEM_TRAY_S0
+);
+
+pub struct Atoms<'a> {
+    conn: &'a xcb::Connection,
+    cache: RefCell<HashMap<String, xcb::Atom>>
+}
+
+impl<'a> Atoms<'a> {
+    pub fn new(conn: &xcb::Connection) -> Atoms {
+        Atoms {
+            conn: conn,
+            cache: RefCell::new(HashMap::new())
+        }
+    }
+
+    pub fn get(&self, name: &str) -> xcb::Atom {
+        let mut cache = self.cache.borrow_mut();
+        if cache.contains_key(name) {
+            *cache.get(name).unwrap()
+        }
+        else {
+            let atom = xcb::intern_atom(self.conn, false, name).get_reply().unwrap().atom();
+            cache.insert(name.to_string(), atom);
+            atom
+        }
+    }
+}

+ 9 - 0
src/main.rs

@@ -3,6 +3,8 @@ extern crate chan;
 extern crate chan_signal;
 extern crate xcb;
 
+mod atom;
+
 use std::thread;
 use std::sync::Arc;
 
@@ -11,10 +13,17 @@ fn main() {
 
     if let Ok((conn, preferred)) = xcb::Connection::connect(None) {
         let conn = Arc::new(conn);
+        let atoms = atom::Atoms::new(&conn);
 
         let setup = conn.get_setup();
         let screen = setup.roots().nth(preferred as usize).unwrap();
 
+        let owner = xcb::get_selection_owner(&conn, atoms.get(&atom::_NET_SYSTEM_TRAY_S0)).get_reply().unwrap().owner();
+        if owner != xcb::NONE {
+            println!("Another system tray is already running");
+            return
+        }
+
         let window = conn.generate_id();
         xcb::create_window(
             &conn,