diff --git a/src/cmds.rs b/src/cmds.rs index 7c46cbb..7726703 100644 --- a/src/cmds.rs +++ b/src/cmds.rs @@ -108,6 +108,9 @@ pub enum SwayrCommand { 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. @@ -302,6 +305,9 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { 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()) } @@ -650,6 +656,35 @@ pub fn switch_workspace_or_window(extra_props: &HashMap) { } } +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); diff --git a/src/tree.rs b/src/tree.rs index 285f562..db8b4c9 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -290,6 +290,22 @@ impl<'a> Tree<'a> { self.as_display_nodes(v, IndentLevel::WorkspacesZeroWindowsOne) } + pub fn get_workspaces_containers_and_windows(&self) -> Vec { + let workspaces = self.sorted_nodes_of_type(Type::Workspace); + let mut v: Vec<&s::Node> = vec![]; + for ws in workspaces { + // TODO: implement me! + } + + // Rotate until we have the second recently used workspace in front. + v.rotate_left(1); + while v[0].get_type() != Type::Workspace { + v.rotate_left(1); + } + + self.as_display_nodes(v, IndentLevel::TreeDepth(2)) + } + pub fn is_child_of_tiled_container(&self, id: i64) -> bool { match self.get_parent_node(id) { Some(n) => {