Browse Source

Implement positioning

Thomas Dy 7 years ago
parent
commit
bcac904214
2 changed files with 55 additions and 8 deletions
  1. 9 1
      src/main.rs
  2. 46 7
      src/tray.rs

+ 9 - 1
src/main.rs

@@ -23,7 +23,15 @@ fn main() {
             return
         }
 
-        let mut tray = tray::Tray::new(&conn, &atoms, preferred as usize, 20);
+        let dir = "top-right";
+        let dir = match dir {
+            "top-right" => tray::TOP_RIGHT,
+            "bottom-left" => tray::BOTTOM_LEFT,
+            "bottom-right" => tray::BOTTOM_RIGHT,
+            _ => tray::TOP_LEFT
+        };
+
+        let mut tray = tray::Tray::new(&conn, &atoms, preferred as usize, 20, dir);
         tray.create();
         if !tray.take_selection() {
             println!("Could not take ownership of tray selection. Maybe another tray is also running?");

+ 46 - 7
src/tray.rs

@@ -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);
         }