Rename con to tree

timeout_old
Tassilo Horn 3 years ago
parent 566a27a9a6
commit 1c1b155e95
  1. 76
      src/cmds.rs
  2. 20
      src/demon.rs
  3. 15
      src/layout.rs
  4. 2
      src/lib.rs
  5. 71
      src/tree.rs

@ -15,10 +15,10 @@
//! Functions and data structures of the swayr client. //! Functions and data structures of the swayr client.
use crate::con;
use crate::con::NodeMethods;
use crate::config as cfg; use crate::config as cfg;
use crate::layout; use crate::layout;
use crate::tree as t;
use crate::tree::NodeMethods;
use crate::util; use crate::util;
use crate::util::DisplayFormat; use crate::util::DisplayFormat;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -162,7 +162,7 @@ impl SwayrCommand {
pub struct ExecSwayrCmdArgs<'a> { pub struct ExecSwayrCmdArgs<'a> {
pub cmd: &'a SwayrCommand, pub cmd: &'a SwayrCommand,
pub extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, pub extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
} }
impl DisplayFormat for SwayrCommand { impl DisplayFormat for SwayrCommand {
@ -172,7 +172,7 @@ impl DisplayFormat for SwayrCommand {
} }
} }
fn always_true(_x: &con::DisplayNode) -> bool { fn always_true(_x: &t::DisplayNode) -> bool {
true true
} }
@ -216,7 +216,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Forward, Direction::Forward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| { Box::new(|dn: &t::DisplayNode| {
!dn.node.is_floating() !dn.node.is_floating()
&& dn.tree.is_child_of_tiled_container(dn.node.id) && dn.tree.is_child_of_tiled_container(dn.node.id)
}), }),
@ -225,7 +225,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Backward, Direction::Backward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| { Box::new(|dn: &t::DisplayNode| {
!dn.node.is_floating() !dn.node.is_floating()
&& dn.tree.is_child_of_tiled_container(dn.node.id) && dn.tree.is_child_of_tiled_container(dn.node.id)
}), }),
@ -235,7 +235,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Forward, Direction::Forward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| { Box::new(|dn: &t::DisplayNode| {
!dn.node.is_floating() !dn.node.is_floating()
&& dn && dn
.tree .tree
@ -248,7 +248,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Backward, Direction::Backward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| { Box::new(|dn: &t::DisplayNode| {
!dn.node.is_floating() !dn.node.is_floating()
&& dn && dn
.tree .tree
@ -261,7 +261,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Forward, Direction::Forward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| dn.node.is_floating()), Box::new(|dn: &t::DisplayNode| dn.node.is_floating()),
) )
} }
SwayrCommand::PrevFloatingWindow { windows } => { SwayrCommand::PrevFloatingWindow { windows } => {
@ -269,7 +269,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
Direction::Backward, Direction::Backward,
windows, windows,
&*props.read().unwrap(), &*props.read().unwrap(),
Box::new(|dn: &con::DisplayNode| dn.node.is_floating()), Box::new(|dn: &t::DisplayNode| dn.node.is_floating()),
) )
} }
SwayrCommand::NextWindowOfSameLayout { windows } => { SwayrCommand::NextWindowOfSameLayout { windows } => {
@ -403,14 +403,14 @@ pub fn get_tree(include_scratchpad: bool) -> s::Node {
} }
pub fn switch_to_urgent_or_lru_window( pub fn switch_to_urgent_or_lru_window(
extra_props: &HashMap<i64, con::ExtraProps>, extra_props: &HashMap<i64, t::ExtraProps>,
) { ) {
let root = get_tree(false); let root = get_tree(false);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
if let Some(win) = tree.get_windows().get(0) { if let Some(win) = tree.get_windows().get(0) {
println!( println!(
"Switching to {}, id: {}", "Switching to {}, id: {}",
win.node.get_app_name(), win.node.get_app_name().unwrap_or_else(|e| e),
win.node.id win.node.id
); );
focus_window_by_id(win.node.id) focus_window_by_id(win.node.id)
@ -466,9 +466,9 @@ fn handle_non_matching_input(input: &str) {
} }
} }
pub fn switch_window(extra_props: &HashMap<i64, con::ExtraProps>) { pub fn switch_window(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(true); let root = get_tree(true);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
match util::select_from_menu("Switch to window", &tree.get_windows()) { match util::select_from_menu("Switch to window", &tree.get_windows()) {
Ok(window) => focus_window_by_id(window.node.id), Ok(window) => focus_window_by_id(window.node.id),
@ -486,11 +486,11 @@ pub enum Direction {
pub fn focus_window_in_direction( pub fn focus_window_in_direction(
dir: Direction, dir: Direction,
consider_wins: &ConsiderWindows, consider_wins: &ConsiderWindows,
extra_props: &HashMap<i64, con::ExtraProps>, extra_props: &HashMap<i64, t::ExtraProps>,
pred: Box<dyn Fn(&con::DisplayNode) -> bool>, pred: Box<dyn Fn(&t::DisplayNode) -> bool>,
) { ) {
let root = get_tree(false); let root = get_tree(false);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
let mut wins = tree.get_windows(); let mut wins = tree.get_windows();
if consider_wins == &ConsiderWindows::CurrentWorkspace { if consider_wins == &ConsiderWindows::CurrentWorkspace {
@ -512,7 +512,7 @@ pub fn focus_window_in_direction(
lru_a.cmp(&lru_b).reverse() lru_a.cmp(&lru_b).reverse()
}); });
let is_focused_window: Box<dyn Fn(&con::DisplayNode) -> bool> = let is_focused_window: Box<dyn Fn(&t::DisplayNode) -> bool> =
if !wins.iter().any(|w| w.node.focused) { if !wins.iter().any(|w| w.node.focused) {
let last_focused_win_id = wins.get(0).unwrap().node.id; let last_focused_win_id = wins.get(0).unwrap().node.id;
Box::new(move |dn| dn.node.id == last_focused_win_id) Box::new(move |dn| dn.node.id == last_focused_win_id)
@ -520,7 +520,7 @@ pub fn focus_window_in_direction(
Box::new(|dn| dn.node.focused) Box::new(|dn| dn.node.focused)
}; };
let mut iter: Box<dyn Iterator<Item = &con::DisplayNode>> = match dir { let mut iter: Box<dyn Iterator<Item = &t::DisplayNode>> = match dir {
Direction::Forward => Box::new(wins.iter().rev().cycle()), Direction::Forward => Box::new(wins.iter().rev().cycle()),
Direction::Backward => Box::new(wins.iter().cycle()), Direction::Backward => Box::new(wins.iter().cycle()),
}; };
@ -538,10 +538,10 @@ pub fn focus_window_in_direction(
pub fn focus_window_of_same_layout_in_direction( pub fn focus_window_of_same_layout_in_direction(
dir: Direction, dir: Direction,
consider_wins: &ConsiderWindows, consider_wins: &ConsiderWindows,
extra_props: &HashMap<i64, con::ExtraProps>, extra_props: &HashMap<i64, t::ExtraProps>,
) { ) {
let root = get_tree(false); let root = get_tree(false);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
let wins = tree.get_windows(); let wins = tree.get_windows();
let cur_win = wins.get(0); let cur_win = wins.get(0);
@ -577,9 +577,9 @@ pub fn focus_window_of_same_layout_in_direction(
} }
} }
pub fn switch_workspace(extra_props: &HashMap<i64, con::ExtraProps>) { pub fn switch_workspace(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(false); let root = get_tree(false);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
match util::select_from_menu("Switch to workspace", &tree.get_workspaces()) match util::select_from_menu("Switch to workspace", &tree.get_workspaces())
{ {
@ -593,10 +593,10 @@ pub fn switch_workspace(extra_props: &HashMap<i64, con::ExtraProps>) {
} }
pub fn move_focused_container_to_workspace( pub fn move_focused_container_to_workspace(
extra_props: &HashMap<i64, con::ExtraProps>, extra_props: &HashMap<i64, t::ExtraProps>,
) { ) {
let root = get_tree(true); let root = get_tree(true);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
let workspaces = tree.get_workspaces(); let workspaces = tree.get_workspaces();
let val = util::select_from_menu( let val = util::select_from_menu(
@ -622,18 +622,18 @@ pub fn move_focused_container_to_workspace(
} }
} }
pub fn switch_workspace_or_window(extra_props: &HashMap<i64, con::ExtraProps>) { pub fn switch_workspace_or_window(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(true); let root = get_tree(true);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
let ws_or_wins = tree.get_workspaces_and_windows(); let ws_or_wins = tree.get_workspaces_and_windows();
match util::select_from_menu("Select workspace or window", &ws_or_wins) { match util::select_from_menu("Select workspace or window", &ws_or_wins) {
Ok(tn) => match tn.node.get_type() { Ok(tn) => match tn.node.get_type() {
con::Type::Workspace => { t::Type::Workspace => {
if !tn.node.is_scratchpad() { if !tn.node.is_scratchpad() {
run_sway_command(&["workspace", tn.node.get_name()]); run_sway_command(&["workspace", tn.node.get_name()]);
} }
} }
con::Type::Window => focus_window_by_id(tn.node.id), t::Type::Window => focus_window_by_id(tn.node.id),
t => { t => {
eprintln!("Cannot handle {:?} in switch_workspace_or_window", t) eprintln!("Cannot handle {:?} in switch_workspace_or_window", t)
} }
@ -644,9 +644,9 @@ pub fn switch_workspace_or_window(extra_props: &HashMap<i64, con::ExtraProps>) {
} }
} }
pub fn quit_window(extra_props: &HashMap<i64, con::ExtraProps>) { pub fn quit_window(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(true); let root = get_tree(true);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
if let Ok(window) = if let Ok(window) =
util::select_from_menu("Quit window", &tree.get_windows()) util::select_from_menu("Quit window", &tree.get_windows())
@ -655,22 +655,22 @@ pub fn quit_window(extra_props: &HashMap<i64, con::ExtraProps>) {
} }
} }
pub fn quit_workspace_or_window(extra_props: &HashMap<i64, con::ExtraProps>) { pub fn quit_workspace_or_window(extra_props: &HashMap<i64, t::ExtraProps>) {
let root = get_tree(true); let root = get_tree(true);
let tree = con::get_tree(&root, extra_props); let tree = t::get_tree(&root, extra_props);
let ws_or_wins = tree.get_workspaces_and_windows(); let ws_or_wins = tree.get_workspaces_and_windows();
if let Ok(tn) = if let Ok(tn) =
util::select_from_menu("Quit workspace or window", &ws_or_wins) util::select_from_menu("Quit workspace or window", &ws_or_wins)
{ {
match tn.node.get_type() { match tn.node.get_type() {
con::Type::Workspace => { t::Type::Workspace => {
for win in for win in
tn.node.iter().filter(|n| n.get_type() == con::Type::Window) tn.node.iter().filter(|n| n.get_type() == t::Type::Window)
{ {
quit_window_by_id(win.id) quit_window_by_id(win.id)
} }
} }
con::Type::Window => quit_window_by_id(tn.node.id), t::Type::Window => quit_window_by_id(tn.node.id),
t => { t => {
eprintln!("Cannot handle {:?} in quit_workspace_or_window", t) eprintln!("Cannot handle {:?} in quit_workspace_or_window", t)
} }
@ -754,7 +754,7 @@ fn tab_current_workspace(floating: &ConsiderFloating) {
fn toggle_tab_tile_current_workspace(floating: &ConsiderFloating) { fn toggle_tab_tile_current_workspace(floating: &ConsiderFloating) {
let tree = get_tree(false); let tree = get_tree(false);
let workspaces = tree.nodes_of_type(con::Type::Workspace); let workspaces = tree.nodes_of_type(t::Type::Workspace);
let cur_ws = workspaces.iter().find(|w| w.is_current()).unwrap(); let cur_ws = workspaces.iter().find(|w| w.is_current()).unwrap();
if cur_ws.layout == s::NodeLayout::Tabbed { if cur_ws.layout == s::NodeLayout::Tabbed {
tile_current_workspace(floating, true); tile_current_workspace(floating, true);

@ -16,9 +16,9 @@
//! Functions and data structures of the swayrd demon. //! Functions and data structures of the swayrd demon.
use crate::cmds; use crate::cmds;
use crate::con;
use crate::config; use crate::config;
use crate::layout; use crate::layout;
use crate::tree as t;
use crate::util; use crate::util;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Read; use std::io::Read;
@ -30,7 +30,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use swayipc as s; use swayipc as s;
pub fn run_demon() { pub fn run_demon() {
let extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>> = let extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>> =
Arc::new(RwLock::new(HashMap::new())); Arc::new(RwLock::new(HashMap::new()));
let extra_props_for_ev_handler = extra_props.clone(); let extra_props_for_ev_handler = extra_props.clone();
@ -47,7 +47,7 @@ fn connect_and_subscribe() -> s::Fallible<s::EventStream> {
} }
pub fn monitor_sway_events( pub fn monitor_sway_events(
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) { ) {
let config = config::load_config(); let config = config::load_config();
@ -104,7 +104,7 @@ pub fn monitor_sway_events(
fn handle_window_event( fn handle_window_event(
ev: Box<s::WindowEvent>, ev: Box<s::WindowEvent>,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
config: &config::Config, config: &config::Config,
) -> bool { ) -> bool {
let s::WindowEvent { let s::WindowEvent {
@ -143,7 +143,7 @@ fn handle_window_event(
fn handle_workspace_event( fn handle_workspace_event(
ev: Box<s::WorkspaceEvent>, ev: Box<s::WorkspaceEvent>,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) -> bool { ) -> bool {
let s::WorkspaceEvent { let s::WorkspaceEvent {
change, change,
@ -176,7 +176,7 @@ fn handle_workspace_event(
fn update_last_focus_time( fn update_last_focus_time(
id: i64, id: i64,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) { ) {
let mut write_lock = extra_props.write().unwrap(); let mut write_lock = extra_props.write().unwrap();
if let Some(wp) = write_lock.get_mut(&id) { if let Some(wp) = write_lock.get_mut(&id) {
@ -184,7 +184,7 @@ fn update_last_focus_time(
} else { } else {
write_lock.insert( write_lock.insert(
id, id,
con::ExtraProps { t::ExtraProps {
last_focus_time: get_epoch_time_as_millis(), last_focus_time: get_epoch_time_as_millis(),
last_focus_time_for_next_prev_seq: 0, last_focus_time_for_next_prev_seq: 0,
}, },
@ -194,7 +194,7 @@ fn update_last_focus_time(
fn remove_extra_props( fn remove_extra_props(
id: i64, id: i64,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) { ) {
extra_props.write().unwrap().remove(&id); extra_props.write().unwrap().remove(&id);
} }
@ -207,7 +207,7 @@ fn get_epoch_time_as_millis() -> u128 {
} }
pub fn serve_client_requests( pub fn serve_client_requests(
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) { ) {
match std::fs::remove_file(util::get_swayr_socket_path()) { match std::fs::remove_file(util::get_swayr_socket_path()) {
Ok(()) => println!("Deleted stale socket from previous run."), Ok(()) => println!("Deleted stale socket from previous run."),
@ -236,7 +236,7 @@ pub fn serve_client_requests(
fn handle_client_request( fn handle_client_request(
mut stream: UnixStream, mut stream: UnixStream,
extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
) { ) {
let mut cmd_str = String::new(); let mut cmd_str = String::new();
if stream.read_to_string(&mut cmd_str).is_ok() { if stream.read_to_string(&mut cmd_str).is_ok() {

@ -16,9 +16,9 @@
//! Functions and data structures of the swayrd demon. //! Functions and data structures of the swayrd demon.
use crate::cmds; use crate::cmds;
use crate::con;
use crate::con::NodeMethods;
use crate::config; use crate::config;
use crate::tree as t;
use crate::tree::NodeMethods;
use std::collections::HashMap; use std::collections::HashMap;
use swayipc as s; use swayipc as s;
@ -41,9 +41,9 @@ pub fn auto_tile(res_to_min_width: &HashMap<i32, i32>) {
let min_window_width = &res_to_min_width.get(&output_width); let min_window_width = &res_to_min_width.get(&output_width);
if let Some(min_window_width) = min_window_width { if let Some(min_window_width) = min_window_width {
for container in con::NodeIter::new(output).filter(|n| { for container in output.iter().filter(|n| {
let t = n.get_type(); let t = n.get_type();
t == con::Type::Workspace || t == con::Type::Container t == t::Type::Workspace || t == t::Type::Container
}) { }) {
if container.is_scratchpad() { if container.is_scratchpad() {
println!(" Skipping scratchpad"); println!(" Skipping scratchpad");
@ -58,7 +58,7 @@ pub fn auto_tile(res_to_min_width: &HashMap<i32, i32>) {
for child_win in container for child_win in container
.nodes .nodes
.iter() .iter()
.filter(|n| n.get_type() == con::Type::Window) .filter(|n| n.get_type() == t::Type::Window)
{ {
// Width if we'd split once more. // Width if we'd split once more.
let estimated_width = let estimated_width =
@ -140,14 +140,13 @@ pub fn relayout_current_workspace(
let root = cmds::get_tree(false); let root = cmds::get_tree(false);
let workspaces: Vec<&s::Node> = root let workspaces: Vec<&s::Node> = root
.iter() .iter()
.filter(|n| n.get_type() == con::Type::Workspace) .filter(|n| n.get_type() == t::Type::Workspace)
.collect(); .collect();
if let Some(cur_ws) = workspaces.iter().find(|ws| ws.is_current()) { if let Some(cur_ws) = workspaces.iter().find(|ws| ws.is_current()) {
if let Ok(mut con) = s::Connection::new() { if let Ok(mut con) = s::Connection::new() {
let mut moved_wins: Vec<&s::Node> = vec![]; let mut moved_wins: Vec<&s::Node> = vec![];
let mut focused_win = None; let mut focused_win = None;
for win in for win in cur_ws.iter().filter(|n| n.get_type() == t::Type::Window)
cur_ws.iter().filter(|n| n.get_type() == con::Type::Window)
{ {
if win.focused { if win.focused {
focused_win = Some(win); focused_win = Some(win);

@ -25,8 +25,8 @@
pub mod client; pub mod client;
pub mod cmds; pub mod cmds;
pub mod con;
pub mod config; pub mod config;
pub mod demon; pub mod demon;
pub mod layout; pub mod layout;
pub mod tree;
pub mod util; pub mod util;

@ -32,7 +32,7 @@ pub struct NodeIter<'a> {
} }
impl<'a> NodeIter<'a> { impl<'a> NodeIter<'a> {
pub fn new(node: &'a s::Node) -> NodeIter { fn new(node: &'a s::Node) -> NodeIter {
NodeIter { stack: vec![node] } NodeIter { stack: vec![node] }
} }
} }
@ -66,26 +66,14 @@ pub enum Type {
/// Extension methods for [`swayipc::Node`]. /// Extension methods for [`swayipc::Node`].
pub trait NodeMethods { pub trait NodeMethods {
/// Returns an iterator for this [`swayipc::Node`] and its childres.
fn iter(&self) -> NodeIter; fn iter(&self) -> NodeIter;
/// Returns true if this node is an output.
fn get_type(&self) -> Type; fn get_type(&self) -> Type;
fn get_app_name(&self) -> Result<&str, &str>;
/// Returns the app_id if present, otherwise the window-properties class if
/// present, otherwise "<unknown_app>".
fn get_app_name(&self) -> &str;
fn nodes_of_type(&self, t: Type) -> Vec<&s::Node>; fn nodes_of_type(&self, t: Type) -> Vec<&s::Node>;
fn get_name(&self) -> &str; fn get_name(&self) -> &str;
// Returns true if this node is the scratchpad output or workspace.
fn is_scratchpad(&self) -> bool; fn is_scratchpad(&self) -> bool;
fn is_floating(&self) -> bool; fn is_floating(&self) -> bool;
fn is_current(&self) -> bool;
fn is_current(&self) -> bool {
self.iter().any(|n| n.focused)
}
} }
impl NodeMethods for s::Node { impl NodeMethods for s::Node {
@ -102,6 +90,8 @@ impl NodeMethods for s::Node {
_ => { _ => {
if self.node_type == s::NodeType::Con if self.node_type == s::NodeType::Con
&& self.name.is_none() && self.name.is_none()
&& self.app_id.is_none()
&& self.window_properties.is_none()
&& self.layout != s::NodeLayout::None && self.layout != s::NodeLayout::None
{ {
Type::Container Type::Container
@ -128,17 +118,17 @@ impl NodeMethods for s::Node {
} }
} }
fn get_app_name(&self) -> &str { fn get_app_name(&self) -> Result<&str, &str> {
if let Some(app_id) = &self.app_id { if let Some(app_id) = &self.app_id {
app_id Ok(app_id)
} else if let Some(wp_class) = self } else if let Some(wp_class) = self
.window_properties .window_properties
.as_ref() .as_ref()
.and_then(|wp| wp.class.as_ref()) .and_then(|wp| wp.class.as_ref())
{ {
wp_class Ok(wp_class)
} else { } else {
"<unknown_app>" Err("<unknown_app>")
} }
} }
@ -154,6 +144,10 @@ impl NodeMethods for s::Node {
fn is_floating(&self) -> bool { fn is_floating(&self) -> bool {
self.node_type == s::NodeType::FloatingCon 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. /// Extra properties gathered by swayrd for windows and workspaces.
@ -387,8 +381,10 @@ impl DisplayFormat for DisplayNode<'_> {
// Some apps report, e.g., Gimp-2.10 but the icon is still named // Some apps report, e.g., Gimp-2.10 but the icon is still named
// gimp.png. // gimp.png.
let app_name_no_version = APP_NAME_AND_VERSION_RX let app_name =
.replace(self.node.get_app_name(), "$1"); self.node.get_app_name().unwrap_or("_unknown_app_");
let app_name_no_version =
APP_NAME_AND_VERSION_RX.replace(app_name, "$1");
window_format window_format
.replace("{id}", format!("{}", self.node.id).as_str()) .replace("{id}", format!("{}", self.node.id).as_str())
@ -412,7 +408,7 @@ impl DisplayFormat for DisplayNode<'_> {
"{app_name}", "{app_name}",
&maybe_html_escape( &maybe_html_escape(
html_escape, html_escape,
self.node.get_app_name(), self.node.get_app_name().unwrap_or_else(|e| e),
), ),
) )
.replace( .replace(
@ -433,20 +429,23 @@ impl DisplayFormat for DisplayNode<'_> {
) )
.replace( .replace(
"{app_icon}", "{app_icon}",
util::get_icon(self.node.get_app_name(), &icon_dirs) util::get_icon(
.or_else(|| { self.node.get_app_name().unwrap_or_else(|e| e),
util::get_icon(&app_name_no_version, &icon_dirs) &icon_dirs,
}) )
.or_else(|| { .or_else(|| {
util::get_icon( util::get_icon(&app_name_no_version, &icon_dirs)
&app_name_no_version.to_lowercase(), })
&icon_dirs, .or_else(|| {
) util::get_icon(
}) &app_name_no_version.to_lowercase(),
.or(fallback_icon) &icon_dirs,
.map(|i| i.to_string_lossy().into_owned()) )
.unwrap_or_else(String::new) })
.as_str(), .or(fallback_icon)
.map(|i| i.to_string_lossy().into_owned())
.unwrap_or_else(String::new)
.as_str(),
) )
.replace( .replace(
"{title}", "{title}",
Loading…
Cancel
Save