From e351974c419d6888dcc79162e99fb1efd60b80e9 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Thu, 14 Oct 2021 21:23:07 +0200 Subject: [PATCH] New commands: next/prev-similar-window --- src/cmds.rs | 100 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 28 deletions(-) diff --git a/src/cmds.rs b/src/cmds.rs index e2f99bd..fd8986c 100644 --- a/src/cmds.rs +++ b/src/cmds.rs @@ -90,6 +90,14 @@ pub enum SwayrCommand { #[clap(subcommand)] windows: ConsiderWindows, }, + NextSimilarWindow { + #[clap(subcommand)] + windows: ConsiderWindows, + }, + PrevSimilarWindow { + #[clap(subcommand)] + windows: ConsiderWindows, + }, /// Quit the selected window. QuitWindow, /// Switch to the selected workspace. @@ -153,36 +161,32 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { SwayrCommand::SwitchWindow => { switch_window(Some(&*props.read().unwrap())) } - SwayrCommand::NextWindow { windows } => focus_next_window_in_direction( + SwayrCommand::NextWindow { windows } => focus_window_in_direction( Direction::Forward, windows, Some(&*props.read().unwrap()), Box::new(always_true), ), - SwayrCommand::PrevWindow { windows } => focus_next_window_in_direction( + SwayrCommand::PrevWindow { windows } => focus_window_in_direction( Direction::Backward, windows, Some(&*props.read().unwrap()), Box::new(always_true), ), - SwayrCommand::NextTiledWindow { windows } => { - focus_next_window_in_direction( - Direction::Forward, - windows, - Some(&*props.read().unwrap()), - Box::new(|w: &con::Window| w.is_child_of_tiled_container()), - ) - } - SwayrCommand::PrevTiledWindow { windows } => { - focus_next_window_in_direction( - Direction::Backward, - windows, - Some(&*props.read().unwrap()), - Box::new(|w: &con::Window| w.is_child_of_tiled_container()), - ) - } + SwayrCommand::NextTiledWindow { windows } => focus_window_in_direction( + Direction::Forward, + windows, + Some(&*props.read().unwrap()), + Box::new(|w: &con::Window| w.is_child_of_tiled_container()), + ), + SwayrCommand::PrevTiledWindow { windows } => focus_window_in_direction( + Direction::Backward, + windows, + Some(&*props.read().unwrap()), + Box::new(|w: &con::Window| w.is_child_of_tiled_container()), + ), SwayrCommand::NextTabbedOrStackedWindow { windows } => { - focus_next_window_in_direction( + focus_window_in_direction( Direction::Forward, windows, Some(&*props.read().unwrap()), @@ -192,7 +196,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { ) } SwayrCommand::PrevTabbedOrStackedWindow { windows } => { - focus_next_window_in_direction( + focus_window_in_direction( Direction::Backward, windows, Some(&*props.read().unwrap()), @@ -202,7 +206,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { ) } SwayrCommand::NextFloatingWindow { windows } => { - focus_next_window_in_direction( + focus_window_in_direction( Direction::Forward, windows, Some(&*props.read().unwrap()), @@ -210,13 +214,27 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { ) } SwayrCommand::PrevFloatingWindow { windows } => { - focus_next_window_in_direction( + focus_window_in_direction( Direction::Backward, windows, Some(&*props.read().unwrap()), Box::new(|w: &con::Window| w.is_floating()), ) } + SwayrCommand::NextSimilarWindow { windows } => { + focus_similar_window_in_direction( + Direction::Forward, + windows, + Some(&*props.read().unwrap()), + ) + } + SwayrCommand::PrevSimilarWindow { windows } => { + focus_similar_window_in_direction( + Direction::Backward, + windows, + Some(&*props.read().unwrap()), + ) + } SwayrCommand::QuitWindow => quit_window(Some(&*props.read().unwrap())), SwayrCommand::SwitchWorkspace => { switch_workspace(Some(&*props.read().unwrap())) @@ -347,7 +365,7 @@ pub enum Direction { Forward, } -pub fn focus_next_window_in_direction( +pub fn focus_window_in_direction( dir: Direction, consider_wins: &ConsiderWindows, extra_props: Option<&HashMap>, @@ -373,11 +391,7 @@ pub fn focus_next_window_in_direction( let is_focused_window: Box bool> = if !windows.iter().any(|w| w.is_focused()) { - let last_focused_win_id = - con::get_windows(root, false, extra_props) - .get(0) - .unwrap() - .get_id(); + let last_focused_win_id = windows.get(0).unwrap().get_id(); Box::new(move |w| w.get_id() == last_focused_win_id) } else { Box::new(|w: &con::Window| w.is_focused()) @@ -398,6 +412,36 @@ pub fn focus_next_window_in_direction( } } +pub fn focus_similar_window_in_direction( + dir: Direction, + consider_wins: &ConsiderWindows, + extra_props: Option<&HashMap>, +) { + let root = get_tree(); + let windows = con::get_windows(&root, false, extra_props); + let current_window = windows + .iter() + .find(|w| w.is_focused()) + .or_else(|| windows.get(0)); + + if let Some(current_window) = current_window { + focus_window_in_direction( + dir, + consider_wins, + extra_props, + if current_window.is_floating() { + Box::new(|w| w.is_floating()) + } else if current_window.is_child_of_tabbed_or_stacked_container() { + Box::new(|w| w.is_child_of_tabbed_or_stacked_container()) + } else if current_window.is_child_of_tiled_container() { + Box::new(|w| w.is_child_of_tiled_container()) + } else { + Box::new(always_true) + }, + ) + } +} + pub fn switch_workspace(extra_props: Option<&HashMap>) { let root = get_tree(); let workspaces = con::get_workspaces(&root, false, extra_props);