From 19830838742107dff2fbd623974fac111f582ffc Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sun, 14 Nov 2021 11:51:54 +0100 Subject: [PATCH] finished switch_workspace_container_or_window --- src/config.rs | 29 +++++++++--------- src/tree.rs | 83 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/src/config.rs b/src/config.rs index f1ab53a..2e70ed0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -79,13 +79,13 @@ impl Config { .expect("No format.workspace_format defined.") } - // pub fn get_format_container_format(&self) -> String { - // self.format - // .as_ref() - // .and_then(|f| f.container_format.clone()) - // .or_else(|| Format::default().container_format) - // .expect("No format.container_format defined.") - // } + pub fn get_format_container_format(&self) -> String { + self.format + .as_ref() + .and_then(|f| f.container_format.clone()) + .or_else(|| Format::default().container_format) + .expect("No format.container_format defined.") + } pub fn get_format_indent(&self) -> String { self.format @@ -163,7 +163,7 @@ pub struct Menu { pub struct Format { window_format: Option, workspace_format: Option, - //container_format: Option, + container_format: Option, indent: Option, urgency_start: Option, urgency_end: Option, @@ -217,7 +217,7 @@ impl Default for Format { Format { window_format: Some( "img:{app_icon}:text:{indent}{app_name} — \ - {urgency_start}“{title}”{urgency_end} {layout} \ + {urgency_start}“{title}”{urgency_end} \ on workspace {workspace_name} {marks} \ ({id})" .to_string(), @@ -227,11 +227,12 @@ impl Default for Format { ({id})" .to_string(), ), - // container_format: Some( - // "Container {name} \ - // ({id})" - // .to_string(), - // ), + container_format: Some( + "{indent}Container {layout} \ + on workspace {workspace_name} \ + ({id})" + .to_string(), + ), indent: Some(" ".to_string()), html_escape: Some(true), urgency_start: Some( diff --git a/src/tree.rs b/src/tree.rs index db8b4c9..ebecdbf 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -20,8 +20,10 @@ use crate::util; use crate::util::DisplayFormat; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; +use std::cell::RefCell; use std::cmp; use std::collections::HashMap; +use std::rc::Rc; use swayipc as s; /// Immutable Node Iterator @@ -216,17 +218,7 @@ impl<'a> Tree<'a> { t: Type, ) -> Vec<&s::Node> { let mut v: Vec<&s::Node> = node.nodes_of_type(t); - 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() - } - }); + self.sort_by_lru_time(&mut v); v } @@ -236,7 +228,7 @@ impl<'a> Tree<'a> { fn as_display_nodes( &self, - v: Vec<&'a s::Node>, + v: &[&'a s::Node], indent_level: IndentLevel, ) -> Vec { v.iter() @@ -258,13 +250,13 @@ impl<'a> Tree<'a> { pub fn get_workspaces(&self) -> Vec { let mut v = self.sorted_nodes_of_type(Type::Workspace); 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 { let mut v = self.sorted_nodes_of_type(Type::Window); 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 { @@ -287,23 +279,53 @@ impl<'a> Tree<'a> { 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>>, + ) { + 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 { let workspaces = self.sorted_nodes_of_type(Type::Workspace); - let mut v: Vec<&s::Node> = vec![]; + let v: Rc>> = Rc::new(RefCell::new(vec![])); 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. - v.rotate_left(1); - while v[0].get_type() != Type::Workspace { - v.rotate_left(1); + v.borrow_mut().rotate_left(1); + while v.borrow()[0].get_type() != Type::Workspace { + v.borrow_mut().rotate_left(1); } - - self.as_display_nodes(v, IndentLevel::TreeDepth(2)) + let x = self.as_display_nodes(&*v.borrow(), IndentLevel::TreeDepth(2)); + x } pub fn is_child_of_tiled_container(&self, id: i64) -> bool { @@ -395,9 +417,20 @@ impl DisplayFormat for DisplayNode<'_> { "{name}", &maybe_html_escape(html_escape, self.node.get_name()), ), - Type::Container => { - todo!("DisplayFormat for Container not yet implemented") - } + Type::Container => cfg + .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("", |w| w.get_name()), + ), + ), Type::Window => { let urgency_start = cfg.get_format_urgency_start(); let urgency_end = cfg.get_format_urgency_end();