From 7644be9a532f5d94050ebb142f98174869503221 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sun, 14 Nov 2021 16:57:51 +0100 Subject: [PATCH] Tidy up --- NEWS.md | 7 ++ src/cmds.rs | 318 +++++++++++++++++++++++++--------------------------- 2 files changed, 158 insertions(+), 167 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3039cc1..328e75b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,13 @@ swayr v0.10.0 1 for windows. - The `format.workspace_format` may now include a `{layout}` placeholder which is replaced with the current container's layout. +- New command: `switch-workspace-container-or-window` shows workspaces, + containers, and their windows in the menu program and switches to the + selected one. +- New command: `quit-workspace-container-or-window` shows workspaces, + containers, and their windows in the menu program and quits all windows of + the selected workspace/container, or the selected window. + swayr v0.9.0 diff --git a/src/cmds.rs b/src/cmds.rs index 7726703..bfd2cba 100644 --- a/src/cmds.rs +++ b/src/cmds.rs @@ -52,6 +52,20 @@ pub enum SwayrCommand { SwitchToUrgentOrLRUWindow, /// Focus the selected window. SwitchWindow, + /// Switch to the selected workspace. + SwitchWorkspace, + /// Switch to the selected workspace or focus the selected window. + SwitchWorkspaceOrWindow, + /// Switch to the selected workspace or focus the selected container, or + /// window. + SwitchWorkspaceContainerOrWindow, + /// Quit the selected window. + QuitWindow, + /// Quit all windows of selected workspace or the selected window. + QuitWorkspaceOrWindow, + /// Quit all windows of selected workspace, or container or the selected + /// window. + QuitWorkspaceContainerOrWindow, /// Focus the next window in LRU order. NextWindow { #[clap(subcommand)] @@ -102,18 +116,8 @@ pub enum SwayrCommand { #[clap(subcommand)] windows: ConsiderWindows, }, - /// Quit the selected window. - QuitWindow, - /// Switch to the selected workspace. - SwitchWorkspace, - /// Switch to the selected workspace or focus the selected window. - SwitchWorkspaceOrWindow, - /// Switch to the selected workspace or focus the selected container, or - /// window. - SwitchWorkspaceContainerOrWindow, - /// Quit all windows of selected workspace or the selected window. - QuitWorkspaceOrWindow, - /// Move the currently focused window or container to the selected workspace. + /// Move the currently focused window or container to the selected + /// workspace. MoveFocusedToWorkspace, /// Tab or shuffle-and-tile the windows on the current workspace, including /// or excluding floating windows. @@ -209,6 +213,22 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_urgent_or_lru_window(&*props.read().unwrap()) } SwayrCommand::SwitchWindow => switch_window(&*props.read().unwrap()), + SwayrCommand::SwitchWorkspace => { + switch_workspace(&*props.read().unwrap()) + } + SwayrCommand::SwitchWorkspaceOrWindow => { + switch_workspace_or_window(&*props.read().unwrap()) + } + SwayrCommand::SwitchWorkspaceContainerOrWindow => { + switch_workspace_container_or_window(&*props.read().unwrap()) + } + SwayrCommand::QuitWindow => quit_window(&*props.read().unwrap()), + SwayrCommand::QuitWorkspaceOrWindow => { + quit_workspace_or_window(&*props.read().unwrap()) + } + SwayrCommand::QuitWorkspaceContainerOrWindow => { + quit_workspace_container_or_window(&*props.read().unwrap()) + } SwayrCommand::NextWindow { windows } => focus_window_in_direction( Direction::Forward, windows, @@ -298,19 +318,6 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { SwayrCommand::MoveFocusedToWorkspace => { move_focused_container_to_workspace(&*props.read().unwrap()) } - SwayrCommand::QuitWindow => quit_window(&*props.read().unwrap()), - SwayrCommand::SwitchWorkspace => { - switch_workspace(&*props.read().unwrap()) - } - SwayrCommand::SwitchWorkspaceOrWindow => { - switch_workspace_or_window(&*props.read().unwrap()) - } - SwayrCommand::SwitchWorkspaceContainerOrWindow => { - switch_workspace_container_or_window(&*props.read().unwrap()) - } - SwayrCommand::QuitWorkspaceOrWindow => { - quit_workspace_or_window(&*props.read().unwrap()) - } SwayrCommand::TileWorkspace { floating } => { tile_current_workspace(floating, false) } @@ -393,14 +400,6 @@ fn quit_window_by_id(id: i64) { run_sway_command(&[format!("[con_id={}]", id).as_str(), "kill"]); } -#[deprecated] -pub fn get_tree_old() -> s::Node { - match s::Connection::new() { - Ok(mut con) => con.get_tree().expect("Got no root node"), - Err(err) => panic!("{}", err), - } -} - pub fn get_tree(include_scratchpad: bool) -> s::Node { match s::Connection::new() { Ok(mut con) => { @@ -478,18 +477,133 @@ 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::Workspace => { + if !tn.node.is_scratchpad() { + run_sway_command(&["workspace", tn.node.get_name()]); + } + } + t::Type::Window | t::Type::Container => { + focus_window_by_id(tn.node.id) + } + t => { + eprintln!("Cannot handle {:?} in select_and_focus", t) + } + }, + Err(non_matching_input) => { + handle_non_matching_input(&non_matching_input) + } + } +} + pub fn switch_window(extra_props: &HashMap) { let root = get_tree(true); let tree = t::get_tree(&root, extra_props); + select_and_focus("Select window", &tree.get_windows()); +} - match util::select_from_menu("Switch to window", &tree.get_windows()) { - Ok(window) => focus_window_by_id(window.node.id), - Err(non_matching_input) => { - handle_non_matching_input(&non_matching_input) +pub fn switch_workspace(extra_props: &HashMap) { + let root = get_tree(false); + let tree = t::get_tree(&root, extra_props); + select_and_focus("Select workspace", &tree.get_workspaces()); +} + +pub fn switch_workspace_or_window(extra_props: &HashMap) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + select_and_focus( + "Select workspace, or window", + &tree.get_workspaces_and_windows(), + ); +} + +pub fn switch_workspace_container_or_window( + extra_props: &HashMap, +) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + select_and_focus( + "Select workspace, container, or window", + &tree.get_workspaces_containers_and_windows(), + ); +} + +fn select_and_quit(prompt: &str, choices: &[t::DisplayNode]) { + if let Ok(tn) = util::select_from_menu(prompt, choices) { + match tn.node.get_type() { + t::Type::Workspace | t::Type::Container => { + for win in + tn.node.iter().filter(|n| n.get_type() == t::Type::Window) + { + quit_window_by_id(win.id) + } + } + t::Type::Window => quit_window_by_id(tn.node.id), + t => { + eprintln!("Cannot handle {:?} in quit_workspace_or_window", t) + } } } } +pub fn quit_window(extra_props: &HashMap) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + select_and_quit("Quit window", &tree.get_windows()); +} + +pub fn quit_workspace_or_window(extra_props: &HashMap) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + select_and_quit( + "Quit workspace, or window", + &tree.get_workspaces_and_windows(), + ); +} + +pub fn quit_workspace_container_or_window( + extra_props: &HashMap, +) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + select_and_quit( + "Quit workspace, container, or window", + &tree.get_workspaces_containers_and_windows(), + ); +} + +pub fn move_focused_container_to_workspace( + extra_props: &HashMap, +) { + let root = get_tree(true); + let tree = t::get_tree(&root, extra_props); + let workspaces = tree.get_workspaces(); + + let val = util::select_from_menu( + "Move focused container to workspace", + &workspaces, + ); + let ws_name = &match val { + Ok(workspace) => String::from(workspace.node.get_name()), + Err(input) => String::from(chop_workspace_shortcut(&input)), + }; + + if DIGIT_AND_NAME.is_match(ws_name) { + run_sway_command(&[ + "move", + "container", + "to", + "workspace", + "number", + ws_name, + ]); + } else { + run_sway_command(&["move", "container", "to", "workspace", ws_name]); + } +} + pub enum Direction { Backward, Forward, @@ -589,136 +703,6 @@ pub fn focus_window_of_same_layout_in_direction( } } -pub fn switch_workspace(extra_props: &HashMap) { - let root = get_tree(false); - let tree = t::get_tree(&root, extra_props); - - match util::select_from_menu("Switch to workspace", &tree.get_workspaces()) - { - Ok(workspace) => { - run_sway_command(&["workspace", workspace.node.get_name()]) - } - Err(non_matching_input) => { - handle_non_matching_input(&non_matching_input) - } - } -} - -pub fn move_focused_container_to_workspace( - extra_props: &HashMap, -) { - let root = get_tree(true); - let tree = t::get_tree(&root, extra_props); - let workspaces = tree.get_workspaces(); - - let val = util::select_from_menu( - "Move focused container to workspace", - &workspaces, - ); - let ws_name = &match val { - Ok(workspace) => String::from(workspace.node.get_name()), - Err(input) => String::from(chop_workspace_shortcut(&input)), - }; - - if DIGIT_AND_NAME.is_match(ws_name) { - run_sway_command(&[ - "move", - "container", - "to", - "workspace", - "number", - ws_name, - ]); - } else { - run_sway_command(&["move", "container", "to", "workspace", ws_name]); - } -} - -pub fn switch_workspace_or_window(extra_props: &HashMap) { - let root = get_tree(true); - let tree = t::get_tree(&root, extra_props); - let ws_or_wins = tree.get_workspaces_and_windows(); - match util::select_from_menu("Select workspace or window", &ws_or_wins) { - Ok(tn) => match tn.node.get_type() { - t::Type::Workspace => { - if !tn.node.is_scratchpad() { - run_sway_command(&["workspace", tn.node.get_name()]); - } - } - t::Type::Window => focus_window_by_id(tn.node.id), - t => { - eprintln!("Cannot handle {:?} in switch_workspace_or_window", t) - } - }, - Err(non_matching_input) => { - handle_non_matching_input(&non_matching_input) - } - } -} - -pub fn switch_workspace_container_or_window( - extra_props: &HashMap, -) { - let root = get_tree(true); - let tree = t::get_tree(&root, extra_props); - let ws_or_wins = tree.get_workspaces_containers_and_windows(); - match util::select_from_menu( - "Select workspace, container, or window", - &ws_or_wins, - ) { - Ok(tn) => match tn.node.get_type() { - t::Type::Workspace => { - if !tn.node.is_scratchpad() { - run_sway_command(&["workspace", tn.node.get_name()]); - } - } - t::Type::Window | t::Type::Container => { - focus_window_by_id(tn.node.id) - } - t => { - eprintln!("Cannot handle {:?} in switch_workspace_or_window", t) - } - }, - Err(non_matching_input) => { - handle_non_matching_input(&non_matching_input) - } - } -} - -pub fn quit_window(extra_props: &HashMap) { - let root = get_tree(true); - let tree = t::get_tree(&root, extra_props); - - if let Ok(window) = - util::select_from_menu("Quit window", &tree.get_windows()) - { - quit_window_by_id(window.node.id) - } -} - -pub fn quit_workspace_or_window(extra_props: &HashMap) { - let root = get_tree(true); - let tree = t::get_tree(&root, extra_props); - let ws_or_wins = tree.get_workspaces_and_windows(); - if let Ok(tn) = - util::select_from_menu("Quit workspace or window", &ws_or_wins) - { - match tn.node.get_type() { - t::Type::Workspace => { - for win in - tn.node.iter().filter(|n| n.get_type() == t::Type::Window) - { - quit_window_by_id(win.id) - } - } - t::Type::Window => quit_window_by_id(tn.node.id), - t => { - eprintln!("Cannot handle {:?} in quit_workspace_or_window", t) - } - } - } -} - fn tile_current_workspace(floating: &ConsiderFloating, shuffle: bool) { match layout::relayout_current_workspace( floating == &ConsiderFloating::IncludeFloating,