|
@@ -1,22 +1,47 @@
|
|
|
use atom;
|
|
|
use xcb;
|
|
|
|
|
|
+pub enum HorizontalAlign {
|
|
|
+ Left,
|
|
|
+ Right
|
|
|
+}
|
|
|
+
|
|
|
+pub enum VerticalAlign {
|
|
|
+ Top,
|
|
|
+ Bottom
|
|
|
+}
|
|
|
+
|
|
|
+pub type Position = (VerticalAlign, HorizontalAlign);
|
|
|
+
|
|
|
+pub const TOP_LEFT: Position = (VerticalAlign::Top, HorizontalAlign::Left);
|
|
|
+pub const TOP_RIGHT: Position = (VerticalAlign::Top, HorizontalAlign::Right);
|
|
|
+pub const BOTTOM_LEFT: Position = (VerticalAlign::Bottom, HorizontalAlign::Left);
|
|
|
+pub const BOTTOM_RIGHT: Position = (VerticalAlign::Bottom, HorizontalAlign::Right);
|
|
|
+
|
|
|
pub struct Tray<'a> {
|
|
|
conn: &'a xcb::Connection,
|
|
|
atoms: &'a atom::Atoms<'a>,
|
|
|
screen: usize,
|
|
|
icon_size: u16,
|
|
|
+ position: Position,
|
|
|
window: xcb::Window,
|
|
|
children: Vec<xcb::Window>
|
|
|
}
|
|
|
|
|
|
impl<'a> Tray<'a> {
|
|
|
- pub fn new<'b>(conn: &'b xcb::Connection, atoms: &'b atom::Atoms, screen: usize, icon_size: u16) -> Tray<'b> {
|
|
|
+ pub fn new<'b>(
|
|
|
+ conn: &'b xcb::Connection,
|
|
|
+ atoms: &'b atom::Atoms,
|
|
|
+ screen: usize,
|
|
|
+ icon_size: u16,
|
|
|
+ position: Position
|
|
|
+ ) -> Tray<'b> {
|
|
|
Tray::<'b> {
|
|
|
conn: conn,
|
|
|
atoms: atoms,
|
|
|
screen: screen,
|
|
|
icon_size: icon_size,
|
|
|
+ position: position,
|
|
|
window: conn.generate_id(),
|
|
|
children: vec![]
|
|
|
}
|
|
@@ -59,12 +84,12 @@ impl<'a> Tray<'a> {
|
|
|
xcb::map_window(self.conn, window);
|
|
|
self.conn.flush();
|
|
|
self.children.push(window);
|
|
|
- self.resize();
|
|
|
+ self.reposition();
|
|
|
}
|
|
|
|
|
|
pub fn forget(&mut self, window: xcb::Window) {
|
|
|
self.children.retain(|child| *child != window);
|
|
|
- self.resize();
|
|
|
+ self.reposition();
|
|
|
}
|
|
|
|
|
|
pub fn force_size(&self, window: xcb::Window) {
|
|
@@ -75,11 +100,25 @@ impl<'a> Tray<'a> {
|
|
|
self.conn.flush();
|
|
|
}
|
|
|
|
|
|
- pub fn resize(&self) {
|
|
|
- let len = self.children.len() as u16;
|
|
|
- if len > 0 {
|
|
|
+ pub fn reposition(&self) {
|
|
|
+ let width = self.children.len() as u16 * self.icon_size;
|
|
|
+ if width > 0 {
|
|
|
+ let setup = self.conn.get_setup();
|
|
|
+ let screen = setup.roots().nth(self.screen).unwrap();
|
|
|
+
|
|
|
+ let (ref valign, ref halign) = self.position;
|
|
|
+ let y = match valign {
|
|
|
+ &VerticalAlign::Top => 0,
|
|
|
+ &VerticalAlign::Bottom => screen.height_in_pixels() - self.icon_size
|
|
|
+ };
|
|
|
+ let x = match halign {
|
|
|
+ &HorizontalAlign::Left => 0,
|
|
|
+ &HorizontalAlign::Right => screen.width_in_pixels() - width
|
|
|
+ };
|
|
|
xcb::configure_window(self.conn, self.window, &[
|
|
|
- (xcb::CONFIG_WINDOW_WIDTH as u16, (len * self.icon_size) as u32)
|
|
|
+ (xcb::CONFIG_WINDOW_X as u16, x as u32),
|
|
|
+ (xcb::CONFIG_WINDOW_Y as u16, y as u32),
|
|
|
+ (xcb::CONFIG_WINDOW_WIDTH as u16, width as u32)
|
|
|
]);
|
|
|
xcb::map_window(self.conn, self.window);
|
|
|
}
|