From 37c85880e725a75b124e41595671cd33e0f859a8 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sat, 2 Apr 2022 11:40:46 +0200 Subject: [PATCH] Split basic sway IPC into separate mod; use that from window bar module --- TODO | 1 - src/bar/module/sysinfo.rs | 2 +- src/bar/module/window.rs | 25 ++--- src/cmds.rs | 61 ++++++------ src/ipc.rs | 175 +++++++++++++++++++++++++++++++++ src/layout.rs | 15 +-- src/lib.rs | 1 + src/tree.rs | 197 +++++--------------------------------- 8 files changed, 245 insertions(+), 232 deletions(-) create mode 100644 src/ipc.rs diff --git a/TODO b/TODO index fbf20f1..e69de29 100644 --- a/TODO +++ b/TODO @@ -1 +0,0 @@ -- Switch from lazy_static to once_cell once the latter is in stable rust. diff --git a/src/bar/module/sysinfo.rs b/src/bar/module/sysinfo.rs index a5743fc..1f29d1d 100644 --- a/src/bar/module/sysinfo.rs +++ b/src/bar/module/sysinfo.rs @@ -43,7 +43,7 @@ impl BarModuleFn for BarModuleSysInfo { } fn build(&self) -> s::Block { - let x = String::from("{cpu_usage_avg}"); + let x = self.system.borrow().load_average().one.to_string(); self.system.borrow_mut().refresh_specifics( sysinfo::RefreshKind::new().with_cpu().with_memory(), ); diff --git a/src/bar/module/window.rs b/src/bar/module/window.rs index ee5fbe5..6075e57 100644 --- a/src/bar/module/window.rs +++ b/src/bar/module/window.rs @@ -16,24 +16,18 @@ //! The window `swayrbar` module. use crate::bar::module::BarModuleFn; -use crate::tree::NodeIter; -use std::cell::RefCell; +use crate::ipc; +use crate::ipc::NodeMethods; use swaybar_types as s; -use swayipc as ipc; pub struct BarModuleWindow { pub instance: String, - connection: RefCell, } impl BarModuleFn for BarModuleWindow { fn init() -> Box { Box::new(BarModuleWindow { instance: "0".to_string(), - connection: RefCell::new( - ipc::Connection::new() - .expect("Couldn't get a sway IPC connection"), - ), }) } @@ -46,19 +40,14 @@ impl BarModuleFn for BarModuleWindow { } fn build(&self) -> s::Block { - let x: String = match self.connection.borrow_mut().get_tree() { - Ok(root) => { - let o: Option<&ipc::Node> = - NodeIter::new(&root).find(|n| n.focused); - o.map(|w| w.name.clone().unwrap_or_default()) - .unwrap_or_else(String::new) - } - Err(err) => format!("{}", err), - }; + let root = ipc::get_root_node(false); + let focused_win = root.iter().find(|n| n.focused); + let app_name = focused_win.map_or("", |w| w.get_app_name()); + let title = focused_win.map_or("", |w| w.get_name()); s::Block { name: Some(Self::name()), instance: Some(self.instance.clone()), - full_text: x, + full_text: title.to_string() + " — " + app_name, align: Some(s::Align::Right), markup: Some(s::Markup::Pango), short_text: None, diff --git a/src/cmds.rs b/src/cmds.rs index eb09575..4d2528a 100644 --- a/src/cmds.rs +++ b/src/cmds.rs @@ -16,9 +16,10 @@ //! Functions and data structures of the swayr client. use crate::config as cfg; +use crate::ipc; +use crate::ipc::NodeMethods; use crate::layout; use crate::tree as t; -use crate::tree::NodeMethods; use crate::util; use crate::util::DisplayFormat; use once_cell::sync::Lazy; @@ -500,7 +501,7 @@ pub fn switch_to_app_or_urgent_or_lru_window( name: Option<&str>, extra_props: &HashMap, ) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); let wins = tree.get_windows(); let app_win = @@ -512,7 +513,7 @@ pub fn switch_to_mark_or_urgent_or_lru_window( con_mark: Option<&str>, extra_props: &HashMap, ) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); let wins = tree.get_windows(); let marked_win = con_mark.and_then(|mark| { @@ -584,17 +585,17 @@ fn handle_non_matching_input(input: &str) { fn select_and_focus(prompt: &str, choices: &[t::DisplayNode]) { match util::select_from_menu(prompt, choices) { Ok(tn) => match tn.node.get_type() { - t::Type::Output => { + ipc::Type::Output => { if !tn.node.is_scratchpad() { run_sway_command(&["focus output", tn.node.get_name()]); } } - t::Type::Workspace => { + ipc::Type::Workspace => { if !tn.node.is_scratchpad() { run_sway_command(&["workspace", tn.node.get_name()]); } } - t::Type::Window | t::Type::Container => { + ipc::Type::Window | ipc::Type::Container => { focus_window_by_id(tn.node.id) } t => { @@ -608,25 +609,25 @@ fn select_and_focus(prompt: &str, choices: &[t::DisplayNode]) { } pub fn switch_window(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_focus("Select window", &tree.get_windows()); } pub fn switch_workspace(extra_props: &HashMap) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); select_and_focus("Select workspace", &tree.get_workspaces()); } pub fn switch_output(extra_props: &HashMap) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); select_and_focus("Select output", &tree.get_outputs()); } pub fn switch_workspace_or_window(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_focus( "Select workspace or window", @@ -637,7 +638,7 @@ pub fn switch_workspace_or_window(extra_props: &HashMap) { pub fn switch_workspace_container_or_window( extra_props: &HashMap, ) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_focus( "Select workspace, container or window", @@ -646,7 +647,7 @@ pub fn switch_workspace_container_or_window( } pub fn switch_to(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_focus( "Select output, workspace, container or window", @@ -671,14 +672,14 @@ fn kill_process_by_pid(pid: Option) { fn select_and_quit(prompt: &str, choices: &[t::DisplayNode], kill: bool) { if let Ok(tn) = util::select_from_menu(prompt, choices) { match tn.node.get_type() { - t::Type::Workspace | t::Type::Container => { + ipc::Type::Workspace | ipc::Type::Container => { for win in - tn.node.iter().filter(|n| n.get_type() == t::Type::Window) + tn.node.iter().filter(|n| n.get_type() == ipc::Type::Window) { quit_window_by_id(win.id) } } - t::Type::Window => { + ipc::Type::Window => { if kill { kill_process_by_pid(tn.node.pid) } else { @@ -693,13 +694,13 @@ fn select_and_quit(prompt: &str, choices: &[t::DisplayNode], kill: bool) { } pub fn quit_window(extra_props: &HashMap, kill: bool) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_quit("Quit window", &tree.get_windows(), kill); } pub fn quit_workspace_or_window(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_quit( "Quit workspace or window", @@ -711,7 +712,7 @@ pub fn quit_workspace_or_window(extra_props: &HashMap) { pub fn quit_workspace_container_or_window( extra_props: &HashMap, ) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_quit( "Quit workspace, container or window", @@ -749,7 +750,7 @@ fn move_focused_to_container_or_window(id: i64) { fn select_and_move_focused_to(prompt: &str, choices: &[t::DisplayNode]) { match util::select_from_menu(prompt, choices) { Ok(tn) => match tn.node.get_type() { - t::Type::Output => { + ipc::Type::Output => { if tn.node.is_scratchpad() { run_sway_command_1("move container to scratchpad") } else { @@ -759,14 +760,14 @@ fn select_and_move_focused_to(prompt: &str, choices: &[t::DisplayNode]) { ]) } } - t::Type::Workspace => { + ipc::Type::Workspace => { if tn.node.is_scratchpad() { run_sway_command_1("move container to scratchpad") } else { move_focused_to_workspace_1(tn.node.get_name()) } } - t::Type::Container | t::Type::Window => { + ipc::Type::Container | ipc::Type::Window => { move_focused_to_container_or_window(tn.node.id) } t => log::error!("Cannot move focused to {:?}", t), @@ -779,7 +780,7 @@ fn select_and_move_focused_to(prompt: &str, choices: &[t::DisplayNode]) { } pub fn move_focused_to_workspace(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_move_focused_to( "Move focused container to workspace", @@ -788,7 +789,7 @@ pub fn move_focused_to_workspace(extra_props: &HashMap) { } pub fn move_focused_to(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); select_and_move_focused_to( "Move focused container to workspace or container", @@ -797,14 +798,14 @@ pub fn move_focused_to(extra_props: &HashMap) { } pub fn swap_focused_with(extra_props: &HashMap) { - let root = t::get_root_node(true); + let root = ipc::get_root_node(true); let tree = t::get_tree(&root, extra_props); match util::select_from_menu( "Swap focused with", &tree.get_workspaces_containers_and_windows(), ) { Ok(tn) => match tn.node.get_type() { - t::Type::Workspace | t::Type::Container | t::Type::Window => { + ipc::Type::Workspace | ipc::Type::Container | ipc::Type::Window => { run_sway_command(&[ "swap", "container", @@ -833,14 +834,14 @@ pub fn focus_window_in_direction( extra_props: &HashMap, pred: Box bool>, ) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); let mut wins = tree.get_windows(); if consider_wins == &ConsiderWindows::CurrentWorkspace { let cur_ws = tree.get_current_workspace(); wins.retain(|w| { - tree.get_parent_node_of_type(w.node.id, t::Type::Workspace) + tree.get_parent_node_of_type(w.node.id, ipc::Type::Workspace) .unwrap() .id == cur_ws.id @@ -887,7 +888,7 @@ pub fn focus_window_of_same_layout_in_direction( consider_wins: &ConsiderWindows, extra_props: &HashMap, ) { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let tree = t::get_tree(&root, extra_props); let wins = tree.get_windows(); let cur_win = wins.iter().find(|w| w.node.focused); @@ -999,8 +1000,8 @@ fn tab_current_workspace(floating: &ConsiderFloating) { } fn toggle_tab_tile_current_workspace(floating: &ConsiderFloating) { - let tree = t::get_root_node(false); - let workspaces = tree.nodes_of_type(t::Type::Workspace); + let tree = ipc::get_root_node(false); + let workspaces = tree.nodes_of_type(ipc::Type::Workspace); let cur_ws = workspaces.iter().find(|w| w.is_current()).unwrap(); if cur_ws.layout == s::NodeLayout::Tabbed { tile_current_workspace(floating, true); diff --git a/src/ipc.rs b/src/ipc.rs new file mode 100644 index 0000000..cb62809 --- /dev/null +++ b/src/ipc.rs @@ -0,0 +1,175 @@ +// Copyright (C) 2021-2022 Tassilo Horn +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +//! Basic sway IPC. + +use std::{cell::RefCell, sync::Mutex}; + +use once_cell::sync::Lazy; +use swayipc as s; + +static SWAY_IPC_CONNECTION: Lazy>> = + Lazy::new(|| { + Mutex::new(RefCell::new( + s::Connection::new().expect("Could not open sway IPC connection."), + )) + }); + +pub fn get_root_node(include_scratchpad: bool) -> s::Node { + let mut root = match SWAY_IPC_CONNECTION.lock() { + Ok(cell) => cell.borrow_mut().get_tree().expect("Couldn't get tree"), + Err(err) => panic!("{}", err), + }; + + if !include_scratchpad { + root.nodes.retain(|o| !o.is_scratchpad()); + } + root +} + +/// Immutable Node Iterator +/// +/// Iterates nodes in depth-first order, tiled nodes before floating nodes. +pub struct NodeIter<'a> { + stack: Vec<&'a s::Node>, +} + +impl<'a> NodeIter<'a> { + pub fn new(node: &'a s::Node) -> NodeIter { + NodeIter { stack: vec![node] } + } +} + +impl<'a> Iterator for NodeIter<'a> { + type Item = &'a s::Node; + + fn next(&mut self) -> Option { + if let Some(node) = self.stack.pop() { + for n in &node.floating_nodes { + self.stack.push(n); + } + for n in &node.nodes { + self.stack.push(n); + } + Some(node) + } else { + None + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Type { + Root, + Output, + Workspace, + Container, + Window, +} + +/// Extension methods for [`swayipc::Node`]. +pub trait NodeMethods { + fn iter(&self) -> NodeIter; + fn get_type(&self) -> Type; + fn get_app_name(&self) -> &str; + fn nodes_of_type(&self, t: Type) -> Vec<&s::Node>; + fn get_name(&self) -> &str; + fn is_scratchpad(&self) -> bool; + fn is_floating(&self) -> bool; + fn is_current(&self) -> bool; +} + +impl NodeMethods for s::Node { + fn iter(&self) -> NodeIter { + NodeIter::new(self) + } + + fn get_type(&self) -> Type { + match self.node_type { + s::NodeType::Root => Type::Root, + s::NodeType::Output => Type::Output, + s::NodeType::Workspace => Type::Workspace, + s::NodeType::FloatingCon => Type::Window, + _ => { + if self.node_type == s::NodeType::Con + && self.name.is_none() + && self.app_id.is_none() + && self.pid.is_none() + && self.shell.is_none() + && self.window_properties.is_none() + && self.layout != s::NodeLayout::None + { + Type::Container + } else if (self.node_type == s::NodeType::Con + || self.node_type == s::NodeType::FloatingCon) + // Apparently there can be windows without app_id, name, + // and window_properties.class, e.g., dolphin-emu-nogui. + && self.pid.is_some() + // FIXME: While technically correct, old sway versions (up to + // at least sway-1.4) don't expose shell in IPC. So comment in + // again when all major distros have a recent enough sway + // package. + //&& self.shell.is_some() + { + Type::Window + } else { + panic!( + "Don't know type of node with id {} and node_type {:?}\n{:?}", + self.id, self.node_type, self + ) + } + } + } + } + + fn get_name(&self) -> &str { + if let Some(name) = &self.name { + name.as_ref() + } else { + "" + } + } + + fn get_app_name(&self) -> &str { + if let Some(app_id) = &self.app_id { + app_id + } else if let Some(wp_class) = self + .window_properties + .as_ref() + .and_then(|wp| wp.class.as_ref()) + { + wp_class + } else { + "" + } + } + + fn is_scratchpad(&self) -> bool { + let name = self.get_name(); + name.eq("__i3") || name.eq("__i3_scratch") + } + + fn nodes_of_type(&self, t: Type) -> Vec<&s::Node> { + self.iter().filter(|n| n.get_type() == t).collect() + } + + fn is_floating(&self) -> bool { + self.node_type == s::NodeType::FloatingCon + } + + fn is_current(&self) -> bool { + self.iter().any(|n| n.focused) + } +} diff --git a/src/layout.rs b/src/layout.rs index ac39bef..e2c08d6 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -16,8 +16,8 @@ //! Functions and data structures of the swayrd demon. use crate::config; -use crate::tree as t; -use crate::tree::NodeMethods; +use crate::ipc; +use crate::ipc::NodeMethods; use std::collections::HashMap; use swayipc as s; @@ -42,7 +42,7 @@ pub fn auto_tile(res_to_min_width: &HashMap) { if let Some(min_window_width) = min_window_width { for container in output.iter().filter(|n| { let t = n.get_type(); - t == t::Type::Workspace || t == t::Type::Container + t == ipc::Type::Workspace || t == ipc::Type::Container }) { if container.is_scratchpad() { log::debug!(" Skipping scratchpad"); @@ -57,7 +57,7 @@ pub fn auto_tile(res_to_min_width: &HashMap) { for child_win in container .nodes .iter() - .filter(|n| n.get_type() == t::Type::Window) + .filter(|n| n.get_type() == ipc::Type::Window) { // Width if we'd split once more. let estimated_width = @@ -138,16 +138,17 @@ pub fn relayout_current_workspace( dyn Fn(&mut [&s::Node], &mut s::Connection) -> s::Fallible<()>, >, ) -> s::Fallible<()> { - let root = t::get_root_node(false); + let root = ipc::get_root_node(false); let workspaces: Vec<&s::Node> = root .iter() - .filter(|n| n.get_type() == t::Type::Workspace) + .filter(|n| n.get_type() == ipc::Type::Workspace) .collect(); if let Some(cur_ws) = workspaces.iter().find(|ws| ws.is_current()) { if let Ok(mut con) = s::Connection::new() { let mut moved_wins: Vec<&s::Node> = vec![]; let mut focused_win = None; - for win in cur_ws.iter().filter(|n| n.get_type() == t::Type::Window) + for win in + cur_ws.iter().filter(|n| n.get_type() == ipc::Type::Window) { if win.focused { focused_win = Some(win); diff --git a/src/lib.rs b/src/lib.rs index 14b3fbe..53ddef0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,7 @@ pub mod config; pub mod demon; #[macro_use] pub mod fmt_replace; +pub mod ipc; pub mod layout; pub mod rtfmt; pub mod tree; diff --git a/src/tree.rs b/src/tree.rs index 68262fa..2927ded 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -16,6 +16,8 @@ //! Convenience data structures built from the IPC structs. use crate::config; +use crate::ipc; +use crate::ipc::NodeMethods; use crate::util; use crate::util::DisplayFormat; use once_cell::sync::Lazy; @@ -25,163 +27,8 @@ use std::cell::RefCell; use std::cmp; use std::collections::HashMap; use std::rc::Rc; -use std::sync::Mutex; use swayipc as s; -static SWAY_IPC_CONNECTION: Lazy>> = - Lazy::new(|| { - Mutex::new(RefCell::new( - s::Connection::new().expect("Could not open sway IPC connection."), - )) - }); - -pub fn get_root_node(include_scratchpad: bool) -> s::Node { - let mut root = match SWAY_IPC_CONNECTION.lock() { - Ok(cell) => cell.borrow_mut().get_tree().expect("Couldn't get tree"), - Err(err) => panic!("{}", err), - }; - - if !include_scratchpad { - root.nodes.retain(|o| !o.is_scratchpad()); - } - root -} - -/// Immutable Node Iterator -/// -/// Iterates nodes in depth-first order, tiled nodes before floating nodes. -pub struct NodeIter<'a> { - stack: Vec<&'a s::Node>, -} - -impl<'a> NodeIter<'a> { - pub fn new(node: &'a s::Node) -> NodeIter { - NodeIter { stack: vec![node] } - } -} - -impl<'a> Iterator for NodeIter<'a> { - type Item = &'a s::Node; - - fn next(&mut self) -> Option { - if let Some(node) = self.stack.pop() { - for n in &node.floating_nodes { - self.stack.push(n); - } - for n in &node.nodes { - self.stack.push(n); - } - Some(node) - } else { - None - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum Type { - Root, - Output, - Workspace, - Container, - Window, -} - -/// Extension methods for [`swayipc::Node`]. -pub trait NodeMethods { - fn iter(&self) -> NodeIter; - fn get_type(&self) -> Type; - fn get_app_name(&self) -> &str; - fn nodes_of_type(&self, t: Type) -> Vec<&s::Node>; - fn get_name(&self) -> &str; - fn is_scratchpad(&self) -> bool; - fn is_floating(&self) -> bool; - fn is_current(&self) -> bool; -} - -impl NodeMethods for s::Node { - fn iter(&self) -> NodeIter { - NodeIter::new(self) - } - - fn get_type(&self) -> Type { - match self.node_type { - s::NodeType::Root => Type::Root, - s::NodeType::Output => Type::Output, - s::NodeType::Workspace => Type::Workspace, - s::NodeType::FloatingCon => Type::Window, - _ => { - if self.node_type == s::NodeType::Con - && self.name.is_none() - && self.app_id.is_none() - && self.pid.is_none() - && self.shell.is_none() - && self.window_properties.is_none() - && self.layout != s::NodeLayout::None - { - Type::Container - } else if (self.node_type == s::NodeType::Con - || self.node_type == s::NodeType::FloatingCon) - // Apparently there can be windows without app_id, name, - // and window_properties.class, e.g., dolphin-emu-nogui. - && self.pid.is_some() - // FIXME: While technically correct, old sway versions (up to - // at least sway-1.4) don't expose shell in IPC. So comment in - // again when all major distros have a recent enough sway - // package. - //&& self.shell.is_some() - { - Type::Window - } else { - panic!( - "Don't know type of node with id {} and node_type {:?}\n{:?}", - self.id, self.node_type, self - ) - } - } - } - } - - fn get_name(&self) -> &str { - if let Some(name) = &self.name { - name.as_ref() - } else { - "" - } - } - - fn get_app_name(&self) -> &str { - if let Some(app_id) = &self.app_id { - app_id - } else if let Some(wp_class) = self - .window_properties - .as_ref() - .and_then(|wp| wp.class.as_ref()) - { - wp_class - } else { - "" - } - } - - fn is_scratchpad(&self) -> bool { - let name = self.get_name(); - name.eq("__i3") || name.eq("__i3_scratch") - } - - fn nodes_of_type(&self, t: Type) -> Vec<&s::Node> { - self.iter().filter(|n| n.get_type() == t).collect() - } - - fn is_floating(&self) -> bool { - self.node_type == s::NodeType::FloatingCon - } - - fn is_current(&self) -> bool { - self.iter().any(|n| n.focused) - } -} - /// Extra properties gathered by swayrd for windows and workspaces. #[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub struct ExtraProps { @@ -223,7 +70,7 @@ impl<'a> Tree<'a> { pub fn get_parent_node_of_type( &self, id: i64, - t: Type, + t: ipc::Type, ) -> Option<&&s::Node> { let n = self.get_node_by_id(id); if n.get_type() == t { @@ -248,14 +95,14 @@ impl<'a> Tree<'a> { fn sorted_nodes_of_type_1( &self, node: &'a s::Node, - t: Type, + t: ipc::Type, ) -> Vec<&s::Node> { let mut v: Vec<&s::Node> = node.nodes_of_type(t); self.sort_by_urgency_and_lru_time_1(&mut v); v } - fn sorted_nodes_of_type(&self, t: Type) -> Vec<&s::Node> { + fn sorted_nodes_of_type(&self, t: ipc::Type) -> Vec<&s::Node> { self.sorted_nodes_of_type_1(self.root, t) } @@ -276,7 +123,7 @@ impl<'a> Tree<'a> { pub fn get_current_workspace(&self) -> &s::Node { self.root .iter() - .find(|n| n.get_type() == Type::Workspace && n.is_current()) + .find(|n| n.get_type() == ipc::Type::Workspace && n.is_current()) .expect("No current Workspace") } @@ -284,13 +131,13 @@ impl<'a> Tree<'a> { let outputs: Vec<&s::Node> = self .root .iter() - .filter(|n| n.get_type() == Type::Output && !n.is_scratchpad()) + .filter(|n| n.get_type() == ipc::Type::Output && !n.is_scratchpad()) .collect(); self.as_display_nodes(&outputs, IndentLevel::Fixed(0)) } pub fn get_workspaces(&self) -> Vec { - let mut v = self.sorted_nodes_of_type(Type::Workspace); + let mut v = self.sorted_nodes_of_type(ipc::Type::Workspace); if !v.is_empty() { v.rotate_left(1); } @@ -298,7 +145,7 @@ impl<'a> Tree<'a> { } pub fn get_windows(&self) -> Vec { - let mut v = self.sorted_nodes_of_type(Type::Window); + let mut v = self.sorted_nodes_of_type(ipc::Type::Window); // Rotate, but only non-urgent windows. Those should stay at the front // as they are the most likely switch candidates. let mut x; @@ -322,12 +169,12 @@ impl<'a> Tree<'a> { } pub fn get_workspaces_and_windows(&self) -> Vec { - let workspaces = self.sorted_nodes_of_type(Type::Workspace); + let workspaces = self.sorted_nodes_of_type(ipc::Type::Workspace); let mut first = true; let mut v = vec![]; for ws in workspaces { v.push(ws); - let mut wins = self.sorted_nodes_of_type_1(ws, Type::Window); + let mut wins = self.sorted_nodes_of_type_1(ws, ipc::Type::Window); if first && !wins.is_empty() { wins.rotate_left(1); first = false; @@ -371,7 +218,7 @@ impl<'a> Tree<'a> { pub fn get_outputs_workspaces_containers_and_windows( &self, ) -> Vec { - let outputs = self.sorted_nodes_of_type(Type::Output); + let outputs = self.sorted_nodes_of_type(ipc::Type::Output); let v: Rc>> = Rc::new(RefCell::new(vec![])); for o in outputs { self.push_subtree_sorted(o, Rc::clone(&v)); @@ -382,7 +229,7 @@ impl<'a> Tree<'a> { } pub fn get_workspaces_containers_and_windows(&self) -> Vec { - let workspaces = self.sorted_nodes_of_type(Type::Workspace); + let workspaces = self.sorted_nodes_of_type(ipc::Type::Workspace); let v: Rc>> = Rc::new(RefCell::new(vec![])); for ws in workspaces { self.push_subtree_sorted(ws, Rc::clone(&v)); @@ -477,11 +324,11 @@ impl DisplayFormat for DisplayNode<'_> { APP_NAME_AND_VERSION_RX.replace(self.node.get_app_name(), "$1"); let fmt = match self.node.get_type() { - Type::Root => String::from("Cannot format Root"), - Type::Output => cfg.get_format_output_format(), - Type::Workspace => cfg.get_format_workspace_format(), - Type::Container => cfg.get_format_container_format(), - Type::Window => cfg.get_format_window_format(), + ipc::Type::Root => String::from("Cannot format Root"), + ipc::Type::Output => cfg.get_format_output_format(), + ipc::Type::Workspace => cfg.get_format_workspace_format(), + ipc::Type::Container => cfg.get_format_container_format(), + ipc::Type::Window => cfg.get_format_window_format(), }; let fmt = fmt .replace( @@ -529,11 +376,11 @@ impl DisplayFormat for DisplayNode<'_> { "name" | "title" => self.node.get_name(), "output_name" => self .tree - .get_parent_node_of_type(self.node.id, Type::Output) + .get_parent_node_of_type(self.node.id, ipc::Type::Output) .map_or("", |w| w.get_name()), "workspace_name" => self .tree - .get_parent_node_of_type(self.node.id, Type::Workspace) + .get_parent_node_of_type(self.node.id, ipc::Type::Workspace) .map_or("", |w| w.get_name()), "marks" => format_marks(&self.node.marks), }) @@ -544,8 +391,8 @@ impl DisplayFormat for DisplayNode<'_> { IndentLevel::Fixed(level) => level as usize, IndentLevel::WorkspacesZeroWindowsOne => { match self.node.get_type(){ - Type::Workspace => 0, - Type::Window => 1, + ipc::Type::Workspace => 0, + ipc::Type::Window => 1, _ => panic!("Only Workspaces and Windows expected. File a bug report!") } }