Rouven Czerwinski: 1 Implement window and container stealing 3 files changed, 56 insertions(+), 0 deletions(-)
Hi Tassilo,
That looks a lot more usable, thanks for the guidance and review so far. I’ll get around to a v3 tomorrow. Best regards, Rouven
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~tsdh/public-inbox/patches/36381/mbox | git am -3Learn more about email & git
This allows the user to steal a window or container from another workspace into the current workspace. Very useful to get an open document which you know is on some workspace, but needs to be moved into the current one. --- v2: - implement command to also select containers - add logging messages to select_and_steal() - add README entries - add a new get_window_and_containers() tree method README.md | 6 ++++++ swayr/src/cmds.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ swayr/src/tree.rs | 7 +++++++ 3 files changed, 56 insertions(+) diff --git a/README.md b/README.md index a21fe09..b4fd1ae 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,12 @@ output, etc.) and act on that. * `switch-window` displays all windows in the order urgent first, then last-recently-used, focused last and focuses the selected. +* `steal-window` displays all windows in order urgent first, the + last-recently-used, focused last and moves the window into the current + workspace. +* `steal-window-or-container` displays all windows and containers in order + urgent first, the last-recently-used, focused last and moves the window or + container into the current workspace. * `switch-workspace` displays all workspaces in LRU order and switches to the selected one. * `switch-output` shows all outputs in the menu and focuses the selected one. diff --git a/swayr/src/cmds.rs b/swayr/src/cmds.rs index 090b77a..743eaf2 100644 --- a/swayr/src/cmds.rs +++ b/swayr/src/cmds.rs @@ -150,6 +150,12 @@ pub enum SwayrCommand { }, /// Focus the selected window. SwitchWindow, + /// Steal the selected window from another workspace into the current + /// workspace. + StealWindow, + /// Steal the selected window or container from another workspace into the + /// current workspace. + StealWindowOrContainer, /// Switch to the selected workspace. SwitchWorkspace, /// Switch to the selected workspace. @@ -440,6 +446,8 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { ) } SwayrCommand::SwitchWindow => switch_window(fdata), + SwayrCommand::StealWindow => steal_window(fdata), + SwayrCommand::StealWindowOrContainer => steal_window_or_container(fdata), SwayrCommand::SwitchWorkspace => switch_workspace(fdata), SwayrCommand::SwitchOutput => switch_output(), SwayrCommand::SwitchWorkspaceOrWindow => { @@ -580,6 +588,8 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { SwayrCommand::SwapFocusedWith, SwayrCommand::QuitWorkspaceOrWindow, SwayrCommand::SwitchWindow, + SwayrCommand::StealWindow, + SwayrCommand::StealWindowOrContainer, SwayrCommand::SwitchWorkspace, SwayrCommand::SwitchOutput, SwayrCommand::SwitchWorkspaceOrWindow, @@ -648,6 +658,11 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { *last_command = args.cmd.clone(); } +fn steal_window_by_id(id: i64) -> i64 { + run_sway_command(&[format!("[con_id={}]", id).as_str(), "move to workspace current"]); + id +} + fn focus_window_by_id(id: i64) -> i64 { run_sway_command(&[format!("[con_id={}]", id).as_str(), "focus"]); id @@ -887,12 +902,40 @@ fn select_and_focus(prompt: &str, choices: &[t::DisplayNode]) { } } +fn select_and_steal(prompt: &str, choices: &[t::DisplayNode]) { + match util::select_from_menu(prompt, choices) { + Ok(tn) => match tn.node.get_type() { + ipc::Type::Window | ipc::Type::Container => { + steal_window_by_id(tn.node.id); + }, + t => { + log::error!("Cannot handle {:?} in select_and_steal", t) + } + }, + Err(non_matching_input) => { + log::error!("Cannot handle {:?} in select and steal", non_matching_input) + } + } +} + pub fn switch_window(fdata: &FocusData) { let root = ipc::get_root_node(true); let tree = t::get_tree(&root); select_and_focus("Select window", &tree.get_windows(fdata)); } +pub fn steal_window(fdata: &FocusData) { + let root = ipc::get_root_node(true); + let tree = t::get_tree(&root); + select_and_steal("Select window", &tree.get_windows(fdata)); +} + +pub fn steal_window_or_container(fdata: &FocusData) { + let root = ipc::get_root_node(true); + let tree = t::get_tree(&root); + select_and_steal("Select window or container", &tree.get_windows_and_containers(fdata)); +} + pub fn switch_workspace(fdata: &FocusData) { let root = ipc::get_root_node(false); let tree = t::get_tree(&root); diff --git a/swayr/src/tree.rs b/swayr/src/tree.rs index 877780d..a27057f 100644 --- a/swayr/src/tree.rs +++ b/swayr/src/tree.rs @@ -156,6 +156,13 @@ impl<'a> Tree<'a> { self.as_display_nodes(&x, IndentLevel::Fixed(0)) } + pub fn get_windows_and_containers(&self, fdata: &FocusData) -> Vec<DisplayNode> { + let mut v = self.get_windows(fdata); + let c = self.sorted_nodes_of_type(ipc::Type::Container, fdata); + v.append(&mut self.as_display_nodes(&c, IndentLevel::Fixed(0))); + v + }
That's useless because you will get a list of the form emacs ... firefox ... foot ... [... more windows ...] Container [SplitH] on workspace 1 (37) Container [SplitV] on workspace 1 (32) Container [SplitV] on workspace 1 (42) Container [SplitV] on workspace 2 (181) where you don't know what windows are actually contained in, e.g., the container on workspace 2 with id 181. I suggest you simply use the existing Tree::get_workspaces_containers_and_windows() function. If the user selects a workspace, well, then nothing will happen (because the type check in select_and_steal). But at least the user gets presented with a menu showing Workspace 1 Contained [SplitH] Container [SplitV] emacs ... firefox ... Container [SplitV] foot ... Workspace 2 Container [SplitV] where it's obvious from the indentation which container contains which windows. Bye, Tassilo
+ pub fn get_workspaces_and_windows( &self, fdata: &FocusData, -- 2.38.0
builds.sr.ht <builds@sr.ht>swayr/patches/arch.yml: SUCCESS in 4m3s [Implement window and container stealing][0] v2 from [Rouven Czerwinski][1] [0]: https://lists.sr.ht/~tsdh/public-inbox/patches/36381 [1]: mailto:rouven@czerwinskis.de ✓ #869257 SUCCESS swayr/patches/arch.yml https://builds.sr.ht/~tsdh/job/869257
Rouven Czerwinski <rouven@czerwinskis.de> writes: Hi Rouven, we're almost there except for one thing.