| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -20,8 +20,10 @@ use crate::util; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use crate::util::DisplayFormat; | 
					 | 
					 | 
					 | 
					use crate::util::DisplayFormat; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use lazy_static::lazy_static; | 
					 | 
					 | 
					 | 
					use lazy_static::lazy_static; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use serde::{Deserialize, Serialize}; | 
					 | 
					 | 
					 | 
					use serde::{Deserialize, Serialize}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use std::cell::RefCell; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use std::cmp; | 
					 | 
					 | 
					 | 
					use std::cmp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use std::collections::HashMap; | 
					 | 
					 | 
					 | 
					use std::collections::HashMap; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use std::rc::Rc; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use swayipc as s; | 
					 | 
					 | 
					 | 
					use swayipc as s; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Immutable Node Iterator
 | 
					 | 
					 | 
					 | 
					/// Immutable Node Iterator
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -216,17 +218,7 @@ impl<'a> Tree<'a> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        t: Type, | 
					 | 
					 | 
					 | 
					        t: Type, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ) -> Vec<&s::Node> { | 
					 | 
					 | 
					 | 
					    ) -> Vec<&s::Node> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let mut v: Vec<&s::Node> = node.nodes_of_type(t); | 
					 | 
					 | 
					 | 
					        let mut v: Vec<&s::Node> = node.nodes_of_type(t); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v.sort_by(|a, b| { | 
					 | 
					 | 
					 | 
					        self.sort_by_lru_time(&mut v); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if a.urgent && !b.urgent { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                cmp::Ordering::Less | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } else if !a.urgent && b.urgent { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                cmp::Ordering::Greater | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } else { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let lru_a = self.last_focus_time(a.id); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let lru_b = self.last_focus_time(b.id); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                lru_a.cmp(&lru_b).reverse() | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v | 
					 | 
					 | 
					 | 
					        v | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -236,7 +228,7 @@ impl<'a> Tree<'a> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fn as_display_nodes( | 
					 | 
					 | 
					 | 
					    fn as_display_nodes( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        &self, | 
					 | 
					 | 
					 | 
					        &self, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v: Vec<&'a s::Node>, | 
					 | 
					 | 
					 | 
					        v: &[&'a s::Node], | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        indent_level: IndentLevel, | 
					 | 
					 | 
					 | 
					        indent_level: IndentLevel, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ) -> Vec<DisplayNode> { | 
					 | 
					 | 
					 | 
					    ) -> Vec<DisplayNode> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v.iter() | 
					 | 
					 | 
					 | 
					        v.iter() | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -258,13 +250,13 @@ impl<'a> Tree<'a> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pub fn get_workspaces(&self) -> Vec<DisplayNode> { | 
					 | 
					 | 
					 | 
					    pub fn get_workspaces(&self) -> Vec<DisplayNode> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let mut v = self.sorted_nodes_of_type(Type::Workspace); | 
					 | 
					 | 
					 | 
					        let mut v = self.sorted_nodes_of_type(Type::Workspace); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v.rotate_left(1); | 
					 | 
					 | 
					 | 
					        v.rotate_left(1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.as_display_nodes(v, IndentLevel::Fixed(0)) | 
					 | 
					 | 
					 | 
					        self.as_display_nodes(&v, IndentLevel::Fixed(0)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pub fn get_windows(&self) -> Vec<DisplayNode> { | 
					 | 
					 | 
					 | 
					    pub fn get_windows(&self) -> Vec<DisplayNode> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let mut v = self.sorted_nodes_of_type(Type::Window); | 
					 | 
					 | 
					 | 
					        let mut v = self.sorted_nodes_of_type(Type::Window); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v.rotate_left(1); | 
					 | 
					 | 
					 | 
					        v.rotate_left(1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.as_display_nodes(v, IndentLevel::Fixed(0)) | 
					 | 
					 | 
					 | 
					        self.as_display_nodes(&v, IndentLevel::Fixed(0)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pub fn get_workspaces_and_windows(&self) -> Vec<DisplayNode> { | 
					 | 
					 | 
					 | 
					    pub fn get_workspaces_and_windows(&self) -> Vec<DisplayNode> { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -287,23 +279,53 @@ impl<'a> Tree<'a> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            v.rotate_left(1); | 
					 | 
					 | 
					 | 
					            v.rotate_left(1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.as_display_nodes(v, IndentLevel::WorkspacesZeroWindowsOne) | 
					 | 
					 | 
					 | 
					        self.as_display_nodes(&v, IndentLevel::WorkspacesZeroWindowsOne) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    fn sort_by_lru_time(&self, v: &mut Vec<&s::Node>) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        v.sort_by(|a, b| { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if a.urgent && !b.urgent { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                cmp::Ordering::Less | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } else if !a.urgent && b.urgent { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                cmp::Ordering::Greater | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                let lru_a = self.last_focus_time(a.id); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                let lru_b = self.last_focus_time(b.id); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                lru_a.cmp(&lru_b).reverse() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    fn push_subtree_sorted( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        &self, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        n: &'a s::Node, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        v: Rc<RefCell<Vec<&'a s::Node>>>, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        v.borrow_mut().push(n); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        let mut children: Vec<&s::Node> = n.nodes.iter().collect(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        children.append(&mut n.floating_nodes.iter().collect()); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.sort_by_lru_time(&mut children); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for c in children { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            self.push_subtree_sorted(c, Rc::clone(&v)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pub fn get_workspaces_containers_and_windows(&self) -> Vec<DisplayNode> { | 
					 | 
					 | 
					 | 
					    pub fn get_workspaces_containers_and_windows(&self) -> Vec<DisplayNode> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let workspaces = self.sorted_nodes_of_type(Type::Workspace); | 
					 | 
					 | 
					 | 
					        let workspaces = self.sorted_nodes_of_type(Type::Workspace); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        let mut v: Vec<&s::Node> = vec![]; | 
					 | 
					 | 
					 | 
					        let v: Rc<RefCell<Vec<&s::Node>>> = Rc::new(RefCell::new(vec![])); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for ws in workspaces { | 
					 | 
					 | 
					 | 
					        for ws in workspaces { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // TODO: implement me!
 | 
					 | 
					 | 
					 | 
					            self.push_subtree_sorted(ws, Rc::clone(&v)); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Rotate until we have the second recently used workspace in front.
 | 
					 | 
					 | 
					 | 
					        // Rotate until we have the second recently used workspace in front.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        v.rotate_left(1); | 
					 | 
					 | 
					 | 
					        v.borrow_mut().rotate_left(1); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        while v[0].get_type() != Type::Workspace { | 
					 | 
					 | 
					 | 
					        while v.borrow()[0].get_type() != Type::Workspace { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            v.rotate_left(1); | 
					 | 
					 | 
					 | 
					            v.borrow_mut().rotate_left(1); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        let x = self.as_display_nodes(&*v.borrow(), IndentLevel::TreeDepth(2)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.as_display_nodes(v, IndentLevel::TreeDepth(2)) | 
					 | 
					 | 
					 | 
					        x | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pub fn is_child_of_tiled_container(&self, id: i64) -> bool { | 
					 | 
					 | 
					 | 
					    pub fn is_child_of_tiled_container(&self, id: i64) -> bool { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -395,9 +417,20 @@ impl DisplayFormat for DisplayNode<'_> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    "{name}", | 
					 | 
					 | 
					 | 
					                    "{name}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    &maybe_html_escape(html_escape, self.node.get_name()), | 
					 | 
					 | 
					 | 
					                    &maybe_html_escape(html_escape, self.node.get_name()), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                ), | 
					 | 
					 | 
					 | 
					                ), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Type::Container => { | 
					 | 
					 | 
					 | 
					            Type::Container => cfg | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                todo!("DisplayFormat for Container not yet implemented") | 
					 | 
					 | 
					 | 
					                .get_format_container_format() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					                .replace("{indent}", &indent.repeat(self.get_indent_level())) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                .replace("{layout}", format!("{:?}", self.node.layout).as_str()) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                .replace("{id}", format!("{}", self.node.id).as_str()) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                .replace( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    "{workspace_name}", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    &maybe_html_escape( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        html_escape, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        self.tree | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            .get_workspace_node(self.node.id) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            .map_or("<no_workspace>", |w| w.get_name()), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    ), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                ), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Type::Window => { | 
					 | 
					 | 
					 | 
					            Type::Window => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let urgency_start = cfg.get_format_urgency_start(); | 
					 | 
					 | 
					 | 
					                let urgency_start = cfg.get_format_urgency_start(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                let urgency_end = cfg.get_format_urgency_end(); | 
					 | 
					 | 
					 | 
					                let urgency_end = cfg.get_format_urgency_end(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |