diff options
Diffstat (limited to 'src/focus.rs')
-rw-r--r-- | src/focus.rs | 75 |
1 files changed, 14 insertions, 61 deletions
diff --git a/src/focus.rs b/src/focus.rs index b26381e..0c9512f 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -1,80 +1,33 @@ -use xcb::x::{ - self, DeleteProperty, EnterNotifyEvent, FocusInEvent, InputFocus, NotifyDetail, NotifyMode, - SetInputFocus, Window, -}; +use xcb::x::{EnterNotifyEvent, FocusInEvent, NotifyDetail, NotifyMode}; -use crate::{error::*, WM}; +use crate::{error::Result, WM}; impl WM<'_> { /// When a new window is entered, focus it. - pub fn handle_enter_notify(&mut self, e: EnterNotifyEvent) -> Result<()> { + pub fn handle_enter_notify(&mut self, e: &EnterNotifyEvent) -> Result<()> { if (e.mode() != NotifyMode::Normal || e.detail() == NotifyDetail::Inferior) - && e.event() != self.root + && e.event() != self.conn.root() { return Ok(()); } - self.focus_window(e.event()); - self.conn.flush()?; - - Ok(()) - } - - /// When a new window requests focus, focus it. - pub fn handle_focus_in(&mut self, e: FocusInEvent) -> Result<()> { - if self - .clients - .focused_mut() - .map(|c| c.window() != e.event()) - .unwrap_or(true) - { - self.focus_window(e.event()); + if let Some((mon, pos)) = self.clients.find_client_pos(e.event()) { + self.clients.refocus(&self.conn, mon, pos); self.conn.flush()?; } Ok(()) } - /// Attempt to focus the given window, even if it isn't managed. - /// This function sends multiple requests without checking them, so `conn.flush()` should be called after. - pub fn focus_window(&mut self, window: Window) { - if let Some((mon, i)) = self.clients.find_client_pos(window) { - self.refocus(mon, i); - } else { - self.conn.send_request(&SetInputFocus { - revert_to: InputFocus::PointerRoot, - focus: window, - time: x::CURRENT_TIME, - }); - self.conn.send_request(&DeleteProperty { - window, - property: self.atoms.net_active_window, - }); - } - } - - /// Refocus on the client with the given co-ordinates, setting X11 properties as required. - /// If the given index is invalid, focus on the root instead. - /// This function sends multiple requests without checking them, so `conn.flush()` should be called after. - pub fn refocus(&mut self, mon: usize, i: usize) { - self.unfocus(); - if let Some(new) = self.clients.set_focused(mon, i) { - new.set_border(self.conn, self.colours.border_focused()); - // TODO: reset urgent flag - // TODO: something to do with grabbuttons - // TODO: set input focus - // TODO: set active window - // TODO: send wmtakefocus event - } else { - // TODO: focus on root + /// When a new window requests focus, focus it. + pub fn handle_focus_in(&mut self, e: &FocusInEvent) -> Result<()> { + if !self.clients.is_focused(e.event()) { + if let Some((mon, pos)) = self.clients.find_client_pos(e.event()) { + self.clients.refocus(&self.conn, mon, pos); + self.conn.flush()?; + } } - } - /// Unfocus the currently focused window, if it exists. - /// This function sends multiple requests without checking them, so `conn.flush()` should be called after. - pub fn unfocus(&mut self) { - if let Some(old) = self.clients.focused_mut() { - old.set_border(self.conn, self.colours.border_normal()); - } + Ok(()) } } |