|
@@ -1,4 +1,6 @@
|
|
|
+use chan;
|
|
|
use ui;
|
|
|
+use ui::widget;
|
|
|
use ui::x11;
|
|
|
use xcb;
|
|
|
|
|
@@ -7,19 +9,19 @@ use std::sync::Arc;
|
|
|
const CLIENT_MESSAGE: u8 = xcb::CLIENT_MESSAGE | 0x80; // 0x80 flag for client messages
|
|
|
|
|
|
pub struct Tray {
|
|
|
+ tx: chan::Sender<()>,
|
|
|
conn: Arc<x11::Connection>,
|
|
|
window: xcb::Window,
|
|
|
- panel_width: u32,
|
|
|
children: Vec<xcb::Window>,
|
|
|
timestamp: xcb::Timestamp,
|
|
|
}
|
|
|
|
|
|
impl Tray {
|
|
|
- pub fn new(conn: Arc<x11::Connection>, window: xcb::Window, width: u32) -> Tray {
|
|
|
+ pub fn new(tx: chan::Sender<()>, conn: Arc<x11::Connection>, window: xcb::Window) -> Tray {
|
|
|
Tray {
|
|
|
conn: conn,
|
|
|
+ tx: tx,
|
|
|
window: window,
|
|
|
- panel_width: width,
|
|
|
children: vec![],
|
|
|
timestamp: 0
|
|
|
}
|
|
@@ -46,27 +48,22 @@ impl Tray {
|
|
|
ok
|
|
|
}
|
|
|
|
|
|
- fn x_pos(&self, index: usize) -> u32 {
|
|
|
- let tray_width = (index + 1) as u32 * ui::SIZE as u32;
|
|
|
- self.panel_width - tray_width
|
|
|
- }
|
|
|
-
|
|
|
pub fn adopt(&mut self, window: xcb::Window) {
|
|
|
let conn = &self.conn;
|
|
|
xcb::change_window_attributes(conn, window, &[
|
|
|
(xcb::CW_EVENT_MASK, xcb::EVENT_MASK_STRUCTURE_NOTIFY)
|
|
|
]);
|
|
|
- xcb::reparent_window(conn, window, self.window, self.x_pos(self.children.len()) as i16, 0);
|
|
|
+ xcb::reparent_window(conn, window, self.window, 0, 0);
|
|
|
xcb::map_window(conn, window);
|
|
|
self.force_size(window, None);
|
|
|
conn.flush();
|
|
|
self.children.push(window);
|
|
|
- self.reposition();
|
|
|
+ self.tx.send(());
|
|
|
}
|
|
|
|
|
|
pub fn forget(&mut self, window: xcb::Window) {
|
|
|
self.children.retain(|child| *child != window);
|
|
|
- self.reposition();
|
|
|
+ self.tx.send(());
|
|
|
}
|
|
|
|
|
|
pub fn force_size(&self, window: xcb::Window, dimensions: Option<(u16, u16)>) {
|
|
@@ -83,38 +80,25 @@ impl Tray {
|
|
|
conn.flush();
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- pub fn reposition(&self) {
|
|
|
- let conn = &self.conn;
|
|
|
- for (index, child) in self.children.iter().enumerate() {
|
|
|
- let window = *child;
|
|
|
- xcb::configure_window(conn, window, &[
|
|
|
- (xcb::CONFIG_WINDOW_X as u16, self.x_pos(index))
|
|
|
- ]);
|
|
|
- }
|
|
|
- conn.flush();
|
|
|
+impl widget::Widget for Tray {
|
|
|
+ fn width(&self) -> u16 {
|
|
|
+ (self.children.len() * 20) as u16
|
|
|
}
|
|
|
|
|
|
- pub fn finish(&mut self) {
|
|
|
- let conn = &self.conn;
|
|
|
- let screen = conn.default_screen();
|
|
|
-
|
|
|
- for child in self.children.iter() {
|
|
|
+ fn render(&self, x: u16) {
|
|
|
+ for (index, child) in self.children.iter().enumerate() {
|
|
|
let window = *child;
|
|
|
- xcb::change_window_attributes(conn, window, &[
|
|
|
- (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_NO_EVENT)
|
|
|
+ let xpos = x as u32 + index as u32 * 20;
|
|
|
+ xcb::configure_window(&self.conn, window, &[
|
|
|
+ (xcb::CONFIG_WINDOW_X as u16, xpos)
|
|
|
]);
|
|
|
- xcb::unmap_window(conn, window);
|
|
|
- xcb::reparent_window(conn, window, screen.root, 0, 0);
|
|
|
}
|
|
|
- xcb::change_window_attributes(conn, self.window, &[
|
|
|
- (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_STRUCTURE_NOTIFY)
|
|
|
- ]);
|
|
|
- xcb::set_selection_owner(conn, xcb::NONE, conn.atom(x11::_NET_SYSTEM_TRAY_S0), self.timestamp);
|
|
|
- conn.flush();
|
|
|
+ self.conn.flush();
|
|
|
}
|
|
|
|
|
|
- pub fn handle_event(&mut self, event: &xcb::GenericEvent, is_finishing: bool) -> bool {
|
|
|
+ fn handle_event(&mut self, event: &xcb::GenericEvent, is_finishing: bool) -> bool {
|
|
|
if is_finishing {
|
|
|
return false
|
|
|
}
|
|
@@ -161,4 +145,23 @@ impl Tray {
|
|
|
}
|
|
|
false
|
|
|
}
|
|
|
+
|
|
|
+ fn finish(&mut self) {
|
|
|
+ let conn = &self.conn;
|
|
|
+ let screen = conn.default_screen();
|
|
|
+
|
|
|
+ for child in self.children.iter() {
|
|
|
+ let window = *child;
|
|
|
+ xcb::change_window_attributes(conn, window, &[
|
|
|
+ (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_NO_EVENT)
|
|
|
+ ]);
|
|
|
+ xcb::unmap_window(conn, window);
|
|
|
+ xcb::reparent_window(conn, window, screen.root, 0, 0);
|
|
|
+ }
|
|
|
+ xcb::change_window_attributes(conn, self.window, &[
|
|
|
+ (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_STRUCTURE_NOTIFY)
|
|
|
+ ]);
|
|
|
+ xcb::set_selection_owner(conn, xcb::NONE, conn.atom(x11::_NET_SYSTEM_TRAY_S0), self.timestamp);
|
|
|
+ conn.flush();
|
|
|
+ }
|
|
|
}
|