From a645d067b07c0a3cb3360badb5fcad86777f4d01 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sun, 24 Jan 2021 10:30:16 +0100 Subject: [PATCH] New subcommand quit-workspace-or-window --- README.md | 7 +++++-- src/bin/swayr.rs | 13 +++++++++---- src/client.rs | 50 +++++++++++++++++++++++++++++++----------------- src/con.rs | 19 +++--------------- 4 files changed, 49 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index b43b2d5..7d1edf0 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,12 @@ Right now, there are these subcommands: focused last and focuses the selected. * `quit-window` displays all windows and quits the selected one. * `switch-workspace` displays all workspaces in LRU order and switches to the - selected. + selected one. * `switch-workspace-or-window` displays all workspaces and their windows and - allows to switch to either a workspace or window. + switches to the selected workspace or window. +* `quit-workspace-or-window` displays all workspaces and their windows and + allows to quit either the selected workspace (all its windows) or the + selected window. * `execute-swaymsg-command` displays most swaymsg which don't require additional input and executes the selected one. That's handy especially for less often used commands not bound to a key. diff --git a/src/bin/swayr.rs b/src/bin/swayr.rs index 41df1d7..7383fe6 100644 --- a/src/bin/swayr.rs +++ b/src/bin/swayr.rs @@ -18,14 +18,16 @@ struct Opts { #[derive(Clap)] enum SwayrCommand { - /// Switch window with display order urgent first, then LRU order, focused last + /// Focus the selected window SwitchWindow, - /// Quit a window with display order focused first, then reverse-LRU order, urgent last + /// Quit the selected window QuitWindow, - /// Switch workspace with LRU display order + /// Switch to the selected workspace SwitchWorkspace, - /// Switch workspace or window with LRU display order + /// Switch to the selected workspace or focus the selected window SwitchWorkspaceOrWindow, + /// Quit all windows of selected workspace or the selected window + QuitWorkspaceOrWindow, /// Select and execute a swaymsg command ExecuteSwaymsgCommand, } @@ -39,6 +41,9 @@ fn main() { SwayrCommand::SwitchWorkspaceOrWindow => { client::switch_workspace_or_window() } + SwayrCommand::QuitWorkspaceOrWindow => { + client::quit_workspace_or_window() + } SwayrCommand::ExecuteSwaymsgCommand => client::exec_swaymsg_command(), } } diff --git a/src/client.rs b/src/client.rs index 1c1cb6c..8a670fe 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,17 +1,22 @@ use crate::con; +use crate::ipc; use crate::util; use std::fmt; +fn focus_window_by_id(id: &ipc::Id) { + util::swaymsg(&[format!("[con_id={}]", id).as_str(), "focus"]); +} + +fn quit_window_by_id(id: &ipc::Id) { + util::swaymsg(&[format!("[con_id={}]", id).as_str(), "kill"]); +} + pub fn switch_window() { let root = con::get_tree(); - let mut windows = con::get_windows(&root); - windows.sort(); + let windows = con::get_windows(&root); if let Some(window) = con::select_window("Switch to window", &windows) { - util::swaymsg(&[ - format!("[con_id={}]", window.get_id()).as_str(), - "focus", - ]); + focus_window_by_id(&window.get_id()) } } @@ -38,26 +43,35 @@ pub fn switch_workspace_or_window() { con::WsOrWin::Ws { ws } => { util::swaymsg(&["workspace", "number", ws.get_name()]); } - con::WsOrWin::Win { win } => { - util::swaymsg(&[ - format!("[con_id={}]", win.get_id()).as_str(), - "focus", - ]); - } + con::WsOrWin::Win { win } => focus_window_by_id(&win.get_id()), } } } pub fn quit_window() { let root = con::get_tree(); - let mut windows = con::get_windows(&root); - windows.sort_by(|a, b| a.cmp(b).reverse()); + let windows = con::get_windows(&root); if let Some(window) = con::select_window("Quit window", &windows) { - util::swaymsg(&[ - format!("[con_id={}]", window.get_id()).as_str(), - "kill", - ]); + quit_window_by_id(window.get_id()) + } +} + +pub fn quit_workspace_or_window() { + let root = con::get_tree(); + let workspaces = con::get_workspaces(&root, false); + let ws_or_wins = con::WsOrWin::from_workspaces(&workspaces); + if let Some(ws_or_win) = + con::select_workspace_or_window("Quit workspace or window", &ws_or_wins) + { + match ws_or_win { + con::WsOrWin::Ws { ws } => { + for win in &ws.windows { + quit_window_by_id(win.get_id()) + } + } + con::WsOrWin::Win { win } => quit_window_by_id(win.get_id()), + } } } diff --git a/src/con.rs b/src/con.rs index 898453a..c01f071 100644 --- a/src/con.rs +++ b/src/con.rs @@ -134,6 +134,7 @@ fn build_windows( }) } } + v.sort(); v } @@ -159,6 +160,7 @@ fn build_workspaces( windows: wins, }) } + v.sort(); v } @@ -206,22 +208,7 @@ pub fn get_workspaces( .filter(|ws| !ws.is_scratchpad()) .collect() }; - workspaces.sort(); - println!( - "Sorted WS: {:?}", - workspaces - .iter() - .map(Workspace::get_name) - .collect::>() - ); workspaces.rotate_left(1); - println!( - "Rotated WS: {:?}", - workspaces - .iter() - .map(Workspace::get_name) - .collect::>() - ); workspaces } @@ -293,7 +280,7 @@ pub fn select_workspace_or_window<'a>( pub struct Workspace<'a> { node: &'a ipc::Node, con_props: Option, - windows: Vec>, + pub windows: Vec>, } impl Workspace<'_> {