1 use crate::config::Config; 2 use crate::{models::TagId, models::WindowHandle, Window, Workspace}; 3 4 use serde::{Deserialize, Serialize}; 5 use std::collections::{HashMap, VecDeque}; 6 7 use super::MaybeWindowHandle; 8 9 #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)] 10 pub enum FocusBehaviour { 11 Sloppy, 12 ClickTo, 13 Driven, 14 } 15 16 impl Default for FocusBehaviour { default() -> Self17 fn default() -> Self { 18 Self::Sloppy 19 } 20 } 21 22 #[derive(Serialize, Deserialize, Debug, Clone)] 23 pub struct FocusManager { 24 pub behaviour: FocusBehaviour, 25 pub focus_new_windows: bool, 26 pub workspace_history: VecDeque<usize>, 27 pub window_history: VecDeque<MaybeWindowHandle>, 28 pub tag_history: VecDeque<TagId>, 29 pub tags_last_window: HashMap<TagId, WindowHandle>, 30 } 31 32 impl FocusManager { new(config: &impl Config) -> Self33 pub fn new(config: &impl Config) -> Self { 34 Self { 35 behaviour: config.focus_behaviour(), 36 focus_new_windows: config.focus_new_windows(), 37 workspace_history: Default::default(), 38 window_history: Default::default(), 39 tag_history: Default::default(), 40 tags_last_window: Default::default(), 41 } 42 } 43 44 /// Return the currently focused workspace. 45 #[must_use] workspace<'a, 'b>(&self, workspaces: &'a [Workspace]) -> Option<&'b Workspace> where 'a: 'b,46 pub fn workspace<'a, 'b>(&self, workspaces: &'a [Workspace]) -> Option<&'b Workspace> 47 where 48 'a: 'b, 49 { 50 let index = *self.workspace_history.get(0)?; 51 workspaces.get(index) 52 } 53 54 /// Return the currently focused workspace. workspace_mut<'a, 'b>( &self, workspaces: &'a mut Vec<Workspace>, ) -> Option<&'b mut Workspace> where 'a: 'b,55 pub fn workspace_mut<'a, 'b>( 56 &self, 57 workspaces: &'a mut Vec<Workspace>, 58 ) -> Option<&'b mut Workspace> 59 where 60 'a: 'b, 61 { 62 let index = *self.workspace_history.get(0)?; 63 workspaces.get_mut(index) 64 } 65 66 /// Return the currently focused tag if the offset is 0. 67 /// Offset is used to reach further down the history. tag(&self, offset: usize) -> Option<TagId>68 pub fn tag(&self, offset: usize) -> Option<TagId> { 69 self.tag_history.get(offset).copied() 70 } 71 72 /// Return the currently focused window. 73 #[must_use] window<'a, 'b>(&self, windows: &'a [Window]) -> Option<&'b Window> where 'a: 'b,74 pub fn window<'a, 'b>(&self, windows: &'a [Window]) -> Option<&'b Window> 75 where 76 'a: 'b, 77 { 78 let handle = *self.window_history.get(0)?; 79 if let Some(handle) = handle { 80 return windows.iter().find(|w| w.handle == handle); 81 } 82 None 83 } 84 85 /// Return the currently focused window. window_mut<'a, 'b>(&self, windows: &'a mut Vec<Window>) -> Option<&'b mut Window> where 'a: 'b,86 pub fn window_mut<'a, 'b>(&self, windows: &'a mut Vec<Window>) -> Option<&'b mut Window> 87 where 88 'a: 'b, 89 { 90 let handle = *self.window_history.get(0)?; 91 if let Some(handle) = handle { 92 return windows.iter_mut().find(|w| w.handle == handle); 93 } 94 None 95 } 96 } 97