|  | @@ -5,6 +5,19 @@ mod ewmh;
 | 
	
		
			
				|  |  |  use comm;
 | 
	
		
			
				|  |  |  use comm::Channel;
 | 
	
		
			
				|  |  |  use config::Config;
 | 
	
		
			
				|  |  | +use std::thread;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +pub fn wait_for<F>(f: F) -> xcb::Window where F: Fn() -> xcb::Window {
 | 
	
		
			
				|  |  | +    loop {
 | 
	
		
			
				|  |  | +        let w = f();
 | 
	
		
			
				|  |  | +        if w == 0 {
 | 
	
		
			
				|  |  | +            thread::sleep_ms(100);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else {
 | 
	
		
			
				|  |  | +            return w;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  pub fn wm(tx: &Channel, _config: &Config) {
 | 
	
		
			
				|  |  |      if let Ok((conn, screen_num)) = xcb::Connection::connect(None) {
 | 
	
	
		
			
				|  | @@ -14,6 +27,13 @@ pub fn wm(tx: &Channel, _config: &Config) {
 | 
	
		
			
				|  |  |          comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
 | 
	
		
			
				|  |  |          ewmh.watch(ewmh.root, true);
 | 
	
		
			
				|  |  |          ewmh.watch(last_win, true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let stalonetray = wait_for(|| ewmh.search_by_class("stalonetray"));
 | 
	
		
			
				|  |  | +        let panel = wait_for(|| ewmh.search_by_name("__panel_top"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        xcb::configure_window(&conn, stalonetray, &[(xcb::CONFIG_WINDOW_SIBLING as u16, panel), (xcb::CONFIG_WINDOW_STACK_MODE as u16, xcb::STACK_MODE_ABOVE)]);
 | 
	
		
			
				|  |  | +        xcb::change_window_attributes(&conn, stalonetray, &[(xcb::CW_EVENT_MASK, xcb::EVENT_MASK_STRUCTURE_NOTIFY)]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          conn.flush();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          loop {
 | 
	
	
		
			
				|  | @@ -21,19 +41,27 @@ pub fn wm(tx: &Channel, _config: &Config) {
 | 
	
		
			
				|  |  |              match event {
 | 
	
		
			
				|  |  |                  None => { break; }
 | 
	
		
			
				|  |  |                  Some(event) => {
 | 
	
		
			
				|  |  | -                    if event.response_type() == xcb::PROPERTY_NOTIFY {
 | 
	
		
			
				|  |  | -                        let prop_event: &xcb::PropertyNotifyEvent = xcb::cast_event(&event);
 | 
	
		
			
				|  |  | -                        if prop_event.atom() == ewmh._NET_ACTIVE_WINDOW {
 | 
	
		
			
				|  |  | -                            let new_win = ewmh.get_active_window();
 | 
	
		
			
				|  |  | -                            ewmh.watch(last_win, false);
 | 
	
		
			
				|  |  | -                            ewmh.watch(new_win, true);
 | 
	
		
			
				|  |  | -                            conn.flush();
 | 
	
		
			
				|  |  | -                            last_win = new_win;
 | 
	
		
			
				|  |  | -                            comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                        else if prop_event.atom() == ewmh._NET_WM_NAME {
 | 
	
		
			
				|  |  | -                            comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | +                    match event.response_type() {
 | 
	
		
			
				|  |  | +                        xcb::PROPERTY_NOTIFY => {
 | 
	
		
			
				|  |  | +                            let prop_event: &xcb::PropertyNotifyEvent = xcb::cast_event(&event);
 | 
	
		
			
				|  |  | +                            if prop_event.atom() == ewmh._NET_ACTIVE_WINDOW {
 | 
	
		
			
				|  |  | +                                let new_win = ewmh.get_active_window();
 | 
	
		
			
				|  |  | +                                ewmh.watch(last_win, false);
 | 
	
		
			
				|  |  | +                                ewmh.watch(new_win, true);
 | 
	
		
			
				|  |  | +                                conn.flush();
 | 
	
		
			
				|  |  | +                                last_win = new_win;
 | 
	
		
			
				|  |  | +                                comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                            else if prop_event.atom() == ewmh._NET_WM_NAME {
 | 
	
		
			
				|  |  | +                                comm::send(tx, "title", ewmh.get_window_name(last_win).as_ref());
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                        },
 | 
	
		
			
				|  |  | +                        xcb::CONFIGURE_NOTIFY => {
 | 
	
		
			
				|  |  | +                            let event: &xcb::ConfigureNotifyEvent = xcb::cast_event(&event);
 | 
	
		
			
				|  |  | +                            let spacer = format!("%{{O{}}}", event.width()+5);
 | 
	
		
			
				|  |  | +                            comm::send(tx, "spacer", spacer.as_ref());
 | 
	
		
			
				|  |  | +                        },
 | 
	
		
			
				|  |  | +                        _ => ()
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 |