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