Преглед на файлове

Factor out atoms into a macro

Thomas Dy преди 8 години
родител
ревизия
919bf2b7a1
променени са 3 файла, в които са добавени 35 реда и са изтрити 23 реда
  1. 27 0
      src/wm/atom.rs
  2. 5 21
      src/wm/ewmh.rs
  3. 3 2
      src/wm/mod.rs

+ 27 - 0
src/wm/atom.rs

@@ -0,0 +1,27 @@
+extern crate xcb;
+
+fn load_atom(conn: &xcb::Connection, name: &str) -> xcb::Atom {
+    let cookie = xcb::intern_atom(conn, true, name);
+    cookie.get_reply().unwrap().atom()
+}
+
+macro_rules! atoms {
+    ( $( $x:ident ),* ) => {
+        #[allow(non_snake_case)]
+        pub struct Atoms {
+            $(pub $x: xcb::Atom),*
+        }
+
+        pub fn load_atoms(conn: &xcb::Connection) -> Atoms {
+            Atoms {
+                $($x: load_atom(conn, stringify!($x))),*
+            }
+        }
+    }
+}
+
+atoms!(
+    _NET_ACTIVE_WINDOW,
+    _NET_WM_NAME,
+    UTF8_STRING
+);

+ 5 - 21
src/wm/ewmh.rs

@@ -1,20 +1,12 @@
 extern crate xcb;
 
+use wm::atom;
 use std::mem;
 
-const ATOMS: [&'static str; 3] = [
-    "_NET_ACTIVE_WINDOW",
-    "_NET_WM_NAME",
-    "UTF8_STRING"
-];
-
-#[allow(non_snake_case)]
 pub struct EWMH<'a> {
     pub conn: &'a xcb::Connection,
     pub root: xcb::Window,
-    pub _NET_ACTIVE_WINDOW: xcb::Atom,
-    pub _NET_WM_NAME: xcb::Atom,
-    pub UTF8_STRING: xcb::Atom
+    pub atoms: atom::Atoms
 }
 
 pub struct WinClass {
@@ -25,24 +17,16 @@ pub struct WinClass {
 pub fn connect<'a>(conn: &'a xcb::Connection, screen_num: i32) -> EWMH {
     let setup = conn.get_setup();
     let screen = setup.roots().nth(screen_num as usize).unwrap();
-    let atoms: Vec<xcb::Atom> = ATOMS
-        .iter()
-        .map(|name| xcb::intern_atom(&conn, false, name))
-        .map(|cookie| cookie.get_reply().unwrap().atom())
-        .collect();
-
     EWMH {
         conn: conn,
         root: screen.root(),
-        _NET_ACTIVE_WINDOW: atoms[0],
-        _NET_WM_NAME: atoms[1],
-        UTF8_STRING: atoms[2]
+        atoms: atom::load_atoms(conn)
     }
 }
 
 impl<'a> EWMH<'a> {
     pub fn get_active_window(&self) -> xcb::Window {
-        let cookie = xcb::get_property(&self.conn, false, self.root, self._NET_ACTIVE_WINDOW, xcb::ATOM_WINDOW, 0, 4);
+        let cookie = xcb::get_property(&self.conn, false, self.root, self.atoms._NET_ACTIVE_WINDOW, xcb::ATOM_WINDOW, 0, 4);
         let reply = cookie.get_reply().unwrap();
         if reply.value_len() == 0 {
             0
@@ -54,7 +38,7 @@ impl<'a> EWMH<'a> {
     }
 
     pub fn get_window_name(&self, win: xcb::Window) -> String {
-        let cookie = xcb::get_property(&self.conn, false, win, self._NET_WM_NAME, self.UTF8_STRING, 0, 100);
+        let cookie = xcb::get_property(&self.conn, false, win, self.atoms._NET_WM_NAME, self.atoms.UTF8_STRING, 0, 100);
         let reply = cookie.get_reply();
         let value: &str = match reply {
             Ok(reply) => unsafe { mem::transmute(reply.value()) },

+ 3 - 2
src/wm/mod.rs

@@ -1,5 +1,6 @@
 extern crate xcb;
 
+mod atom;
 mod ewmh;
 
 use comm;
@@ -45,7 +46,7 @@ pub fn wm(tx: &Channel, _config: &Config) {
                     match event.response_type() {
                         xcb::PROPERTY_NOTIFY => {
                             let prop_event: &xcb::PropertyNotifyEvent = xcb::cast_event(&event);
-                            if prop_event.atom() == ewmh._NET_ACTIVE_WINDOW {
+                            if prop_event.atom() == ewmh.atoms._NET_ACTIVE_WINDOW {
                                 let new_win = ewmh.get_active_window();
                                 ewmh.watch(last_win, false);
                                 ewmh.watch(new_win, true);
@@ -53,7 +54,7 @@ pub fn wm(tx: &Channel, _config: &Config) {
                                 last_win = new_win;
                                 comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
                             }
-                            else if prop_event.atom() == ewmh._NET_WM_NAME {
+                            else if prop_event.atom() == ewmh.atoms._NET_WM_NAME {
                                 comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
                             }
                         },