summaryrefslogtreecommitdiff
path: root/src/focus.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/focus.rs')
-rw-r--r--src/focus.rs75
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(())
}
}