Thomas Dy 7 роки тому
батько
коміт
3b65addfeb
6 змінених файлів з 124 додано та 109 видалено
  1. 17 18
      src/ui/mod.rs
  2. 20 23
      src/ui/panel.rs
  3. 9 3
      src/ui/sensors.rs
  4. 22 18
      src/ui/title.rs
  5. 49 45
      src/ui/tray.rs
  6. 7 2
      src/ui/widget.rs

+ 17 - 18
src/ui/mod.rs

@@ -19,26 +19,29 @@ pub const SIZE: u16 = 20;
 
 pub fn ui_main(signal: chan::Receiver<chan_signal::Signal>, cfg: &Config) -> i32 {
     if let Some(conn) = x11::Connection::new() {
-        let (tx, rx) = chan::sync(0);
+        let (tx, rx) = chan::sync(10);
         {
+            let tx = tx.clone();
             let conn = conn.clone_connection();
             thread::spawn(move || {
                 loop {
                     match conn.wait_for_event() {
-                        Some(event) => { tx.send(event); },
+                        Some(event) => {
+                            let message = widget::WidgetMessage::XcbEvent(event);
+                            tx.send(message);
+                        },
                         None => { break; }
                     }
                 }
             });
         }
 
-        let (update_tx, update_rx) = chan::sync(10);
-        let (mut panel, panel_rx) = panel::Panel::new(conn, cfg);
+        let mut panel = panel::Panel::new(conn, cfg);
 
         let title = title::Title::new(panel.conn.clone(), panel.make_draw_context());
         panel.add_left_widget(Box::new(title));
 
-        let tray = tray::Tray::new(panel.tx.clone(), panel.conn.clone(), panel.window);
+        let tray = tray::Tray::new(tx.clone(), panel.conn.clone(), panel.window);
         panel.add_right_widget(Box::new(tray));
 
         let sensors = sensors::Sensors::new(panel.make_draw_context(), cfg);
@@ -46,22 +49,18 @@ pub fn ui_main(signal: chan::Receiver<chan_signal::Signal>, cfg: &Config) -> i32
 
         panel.create();
 
-        thread::spawn(move || {
-            loop {
-                update_tx.send(());
-                thread::sleep(time::Duration::from_secs(1));
-            }
-        });
+        {
+            let tx = tx.clone();
+            thread::spawn(move || {
+                loop {
+                    tx.send(widget::WidgetMessage::Update);
+                    thread::sleep(time::Duration::from_secs(1));
+                }
+            });
+        }
 
         loop {
             chan_select!(
-                panel_rx.recv() => {
-                    panel.relayout();
-                },
-                update_rx.recv() => {
-                    panel.update();
-                    panel.relayout();
-                },
                 rx.recv() -> event => {
                     if panel.handle_event(event.unwrap()) {
                         println!("Exiting");

+ 20 - 23
src/ui/panel.rs

@@ -1,4 +1,3 @@
-use chan;
 use config::Config;
 use xcb;
 use ui::ext;
@@ -17,7 +16,6 @@ pub struct Panel {
     pub conn: Arc<x11::Connection>,
     pub window: xcb::Window,
     pub width: u16,
-    pub tx: chan::Sender<()>,
     left_widgets: Vec<Box<Widget>>,
     right_widgets: Vec<Box<Widget>>,
     fonts: Rc<font::FontLoader>,
@@ -26,27 +24,24 @@ pub struct Panel {
 }
 
 impl Panel {
-    pub fn new(conn: x11::Connection, cfg: &Config) -> (Panel, chan::Receiver<()>) {
+    pub fn new(conn: x11::Connection, cfg: &Config) -> Panel {
         let conn = Arc::new(conn);
         let window = conn.generate_id();
         let picture = conn.generate_id();
 
-        let (tx, rx) = chan::sync(10);
         let width = conn.default_screen().width;
         let font_loader = Rc::new(font::FontLoader::from_config(conn.clone_connection(), cfg));
 
-        let panel = Panel {
+        Panel {
             conn: conn,
             width: width,
-            tx: tx,
             window: window,
             left_widgets: vec![],
             right_widgets: vec![],
             fonts: font_loader,
             picture: picture,
             finishing: false
-        };
-        (panel, rx)
+        }
     }
 
     pub fn create(&mut self) {
@@ -108,7 +103,7 @@ impl Panel {
         );
     }
 
-    pub fn handle_event(&mut self, event: xcb::GenericEvent) -> bool {
+    pub fn handle_event(&mut self, event: widget::WidgetMessage) -> bool {
         let finishing = self.finishing;
         let mut should_exit = false;
         if !finishing {
@@ -116,14 +111,22 @@ impl Panel {
                 should_exit |= widget.handle_event(&event);
             }
         }
-        if event.response_type() == xcb::EXPOSE {
-            self.relayout();
-        }
-        if finishing && event.response_type() == xcb::DESTROY_NOTIFY {
-            let event: &xcb::DestroyNotifyEvent = unsafe { xcb::cast_event(&event) };
-            if event.window() == self.window {
-                return true
-            }
+        match event {
+            widget::WidgetMessage::XcbEvent(event) => {
+                if event.response_type() == xcb::EXPOSE {
+                    self.relayout();
+                };
+                if finishing && event.response_type() == xcb::DESTROY_NOTIFY {
+                    let event: &xcb::DestroyNotifyEvent = unsafe { xcb::cast_event(&event) };
+                    if event.window() == self.window {
+                        return true
+                    }
+                }
+            },
+            widget::WidgetMessage::Update =>
+                self.relayout(),
+            widget::WidgetMessage::Relayout =>
+                self.relayout()
         }
         should_exit
     }
@@ -136,12 +139,6 @@ impl Panel {
         self.right_widgets.push(widget);
     }
 
-    pub fn update(&mut self) {
-        for widget in self.widgets_iter() {
-            widget.update()
-        }
-    }
-
     pub fn relayout(&mut self) {
         let color = xcb::render::Color::new(0, 0, 0, 0xFFFF);
         xcb::render::fill_rectangles(

+ 9 - 3
src/ui/sensors.rs

@@ -46,9 +46,15 @@ impl widget::Widget for Sensors {
         sum
     }
 
-    fn update(&mut self) {
-        for ref mut sensor in self.sensors.iter_mut() {
-            sensor.process()
+    fn handle_event(&mut self, event: &widget::WidgetMessage) -> bool {
+        match event {
+            &widget::WidgetMessage::Update =>
+                for ref mut sensor in self.sensors.iter_mut() {
+                    sensor.process()
+                },
+            _ => {}
         }
+
+        false
     }
 }

+ 22 - 18
src/ui/title.rs

@@ -53,24 +53,28 @@ impl Widget for Title {
         0
     }
 
-    fn handle_event(&mut self, event: &xcb::GenericEvent) -> bool {
-        if event.response_type() == xcb::PROPERTY_NOTIFY {
-            let event: &xcb::PropertyNotifyEvent = unsafe { xcb::cast_event(&event) };
-            if event.atom() == self.conn.atom(x11::_NET_ACTIVE_WINDOW) {
-                let new_win = {
-                    let screen = self.conn.default_screen();
-                    screen.get_active_window()
-                };
-                self.conn.watch(self.last_win, false);
-                self.conn.watch(new_win, true);
-                self.last_win = new_win;
-                self.title = self.conn.get_window_name(new_win);
-                self.redraw();
-            }
-            else if event.atom() == self.conn.atom(x11::_NET_WM_NAME) {
-                self.title = self.conn.get_window_name(self.last_win);
-                self.redraw();
-            }
+    fn handle_event(&mut self, event: &widget::WidgetMessage) -> bool {
+        match event {
+            &widget::WidgetMessage::XcbEvent(ref event) =>
+                if event.response_type() == xcb::PROPERTY_NOTIFY {
+                    let event: &xcb::PropertyNotifyEvent = unsafe { xcb::cast_event(&event) };
+                    if event.atom() == self.conn.atom(x11::_NET_ACTIVE_WINDOW) {
+                        let new_win = {
+                            let screen = self.conn.default_screen();
+                            screen.get_active_window()
+                        };
+                        self.conn.watch(self.last_win, false);
+                        self.conn.watch(new_win, true);
+                        self.last_win = new_win;
+                        self.title = self.conn.get_window_name(new_win);
+                        self.redraw();
+                    }
+                    else if event.atom() == self.conn.atom(x11::_NET_WM_NAME) {
+                        self.title = self.conn.get_window_name(self.last_win);
+                        self.redraw();
+                    }
+                },
+            _ => {}
         }
         false
     }

+ 49 - 45
src/ui/tray.rs

@@ -9,7 +9,7 @@ use std::sync::Arc;
 const CLIENT_MESSAGE: u8 = xcb::CLIENT_MESSAGE | 0x80; // 0x80 flag for client messages
 
 pub struct Tray {
-    tx: chan::Sender<()>,
+    tx: chan::Sender<widget::WidgetMessage>,
     conn: Arc<x11::Connection>,
     window: xcb::Window,
     children: Vec<xcb::Window>,
@@ -17,7 +17,7 @@ pub struct Tray {
 }
 
 impl Tray {
-    pub fn new(tx: chan::Sender<()>, conn: Arc<x11::Connection>, window: xcb::Window) -> Tray {
+    pub fn new(tx: chan::Sender<widget::WidgetMessage>, conn: Arc<x11::Connection>, window: xcb::Window) -> Tray {
         Tray {
             conn: conn,
             tx: tx,
@@ -58,12 +58,12 @@ impl Tray {
         self.force_size(window, None);
         conn.flush();
         self.children.push(window);
-        self.tx.send(());
+        self.tx.send(widget::WidgetMessage::Relayout);
     }
 
     pub fn forget(&mut self, window: xcb::Window) {
         self.children.retain(|child| *child != window);
-        self.tx.send(());
+        self.tx.send(widget::WidgetMessage::Relayout);
     }
 
     pub fn force_size(&self, window: xcb::Window, dimensions: Option<(u16, u16)>) {
@@ -97,47 +97,51 @@ impl widget::Widget for Tray {
         }
     }
 
-    fn handle_event(&mut self, event: &xcb::GenericEvent) -> bool {
-        match event.response_type() {
-            xcb::PROPERTY_NOTIFY if self.timestamp == 0 => {
-                let event: &xcb::PropertyNotifyEvent = unsafe { xcb::cast_event(&event) };
-                if !self.take_selection(event.time()) {
-                    println!("Could not take ownership of tray selection. Maybe another tray is also running?");
-                    return true
-                }
-            },
-            CLIENT_MESSAGE => {
-                let event: &xcb::ClientMessageEvent = unsafe { xcb::cast_event(&event) };
-                if event.type_() == self.conn.atom(x11::_NET_SYSTEM_TRAY_OPCODE) {
-                    let data = event.data().data32();
-                    let opcode = data[1];
-                    let window = data[2];
-                    if opcode == 0 {
-                        self.adopt(window);
-                    }
-                }
-            },
-            xcb::REPARENT_NOTIFY => {
-                let event: &xcb::ReparentNotifyEvent = unsafe { xcb::cast_event(&event) };
-                if event.parent() != self.window {
-                    self.forget(event.window());
-                }
-            },
-            xcb::DESTROY_NOTIFY => {
-                let event: &xcb::DestroyNotifyEvent = unsafe { xcb::cast_event(&event) };
-                self.forget(event.window());
-            },
-            xcb::CONFIGURE_NOTIFY => {
-                let event: &xcb::ConfigureNotifyEvent = unsafe { xcb::cast_event(&event) };
-                let window = event.window();
-                if window != self.window {
-                    self.force_size(window, Some((event.width(), event.height())));
-                }
-            },
-            xcb::SELECTION_CLEAR => {
-                self.finish();
-            },
-            _ => {}
+    fn handle_event(&mut self, event: &widget::WidgetMessage) -> bool {
+        match event {
+            &widget::WidgetMessage::XcbEvent(ref event) =>
+                match event.response_type() {
+                    xcb::PROPERTY_NOTIFY if self.timestamp == 0 => {
+                        let event: &xcb::PropertyNotifyEvent = unsafe { xcb::cast_event(&event) };
+                        if !self.take_selection(event.time()) {
+                            println!("Could not take ownership of tray selection. Maybe another tray is also running?");
+                            return true
+                        }
+                    },
+                    CLIENT_MESSAGE => {
+                        let event: &xcb::ClientMessageEvent = unsafe { xcb::cast_event(&event) };
+                        if event.type_() == self.conn.atom(x11::_NET_SYSTEM_TRAY_OPCODE) {
+                            let data = event.data().data32();
+                            let opcode = data[1];
+                            let window = data[2];
+                            if opcode == 0 {
+                                self.adopt(window);
+                            }
+                        }
+                    },
+                    xcb::REPARENT_NOTIFY => {
+                        let event: &xcb::ReparentNotifyEvent = unsafe { xcb::cast_event(&event) };
+                        if event.parent() != self.window {
+                            self.forget(event.window());
+                        }
+                    },
+                    xcb::DESTROY_NOTIFY => {
+                        let event: &xcb::DestroyNotifyEvent = unsafe { xcb::cast_event(&event) };
+                        self.forget(event.window());
+                    },
+                    xcb::CONFIGURE_NOTIFY => {
+                        let event: &xcb::ConfigureNotifyEvent = unsafe { xcb::cast_event(&event) };
+                        let window = event.window();
+                        if window != self.window {
+                            self.force_size(window, Some((event.width(), event.height())));
+                        }
+                    },
+                    xcb::SELECTION_CLEAR => {
+                        self.finish();
+                    },
+                    _ => {}
+                },
+                _ => {}
         }
         false
     }

+ 7 - 2
src/ui/widget.rs

@@ -4,14 +4,19 @@ use ui::font;
 use std::rc::Rc;
 use std::sync::Arc;
 
+pub enum WidgetMessage {
+    Relayout,
+    Update,
+    XcbEvent(xcb::GenericEvent)
+}
+
 pub trait Widget {
     fn init(&mut self) {}
     fn render(&mut self, x: u16);
     fn width(&mut self) -> u16;
-    fn handle_event(&mut self, _event: &xcb::GenericEvent) -> bool {
+    fn handle_event(&mut self, _event: &WidgetMessage) -> bool {
         false
     }
-    fn update(&mut self) {}
     fn finish(&mut self) {}
 }