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