From 286760ade6aefd82cc47f254b8e0be0efefffe65 Mon Sep 17 00:00:00 2001 From: Nabos Date: Thu, 11 Aug 2022 17:36:34 +0200 Subject: [PATCH 1/6] Added Groups --- src/main.rs | 263 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 246 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index ce7718b..08319f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,9 @@ enum Command { #[clap(about = "Focus to another workspace on the same output")] Focus(FocusAction), + #[clap(about = "Focus to output")] + FocusOutput(FocusAction), + #[clap(about = "Focus to another workspace on all the outputs")] FocusAllOutputs(FocusAction), @@ -47,6 +50,12 @@ enum Command { #[clap(about = "Move the focused container to the previous output")] PrevOutput, + #[clap(about = "Move the focused container to the next group")] + NextGroup, + + #[clap(about = "Move the focused container to the previous group")] + PrevGroup, + #[clap(about = "Rearrange already opened workspaces")] RearrangeWorkspaces, } @@ -195,7 +204,7 @@ fn get_current_output_index(stream: &UnixStream) -> usize { let outputs = get_outputs(stream); match outputs.iter().position(|x| x.focused) { - Some(i) => i, + Some(i) => i + 1, None => panic!("WTF! No focused output???"), } } @@ -211,22 +220,200 @@ fn get_current_output_name(stream: &UnixStream) -> String { focused_output_index.to_string() } +fn get_current_workspace(stream: &UnixStream) -> Workspace { + let outputs = get_outputs(stream); + let workspaces = get_workspaces(stream); + workspaces + .into_iter() + .find(|w| w.visible && outputs.iter().find(|o| o.name == w.output).unwrap().focused) + .unwrap() +} + fn move_container_to_workspace(stream: &UnixStream, workspace_index: usize) { - let mut cmd: String = "move container to workspace number ".to_string(); - let full_ws_name = format!("{}{}", get_current_output_index(stream), workspace_index) + if workspace_index < 10 { + let mut cmd: String = "move container to workspace number ".to_string(); + let full_ws_name = format!("{}{}", get_current_output_index(stream), workspace_index) + .parse::() + .unwrap(); + cmd.push_str(&full_ws_name.to_string()); + send_command(stream, &cmd); + } else { + move_container_to_workspace_absolute(stream, workspace_index); + } +} + +fn move_container_to_workspace_absolute(stream: &UnixStream, workspace_index: usize) { + let output_index = (workspace_index / 10) as usize; + let outputs = get_outputs(stream); + let workspaces = get_workspaces(stream); + + // If the workspace already exists + match workspaces.iter().find(|w| w.num == workspace_index) { + Some(_) => { + let mut focus_cmd: String = "move container to workspace number ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + } + None => { + let target_group = workspace_index / 10; + let target_screen_index = match workspaces.iter().find(|w| w.num / 10 == target_group) { + // If other workspaces on the same group exists + Some(other_workspace) => Some( + outputs + .iter() + .enumerate() + .find(|i| i.1.name == other_workspace.output) + .unwrap() + .0, + ), + None => { + // Or if the targeted output is currently connected + if output_index < outputs.len() { + Some(output_index) + } else { + None + } + } + }; + + match target_screen_index { + // If we have to send it to another screen + Some(target_screen_index) => { + let target_output = &outputs[target_screen_index - 1]; + + let current_output_name = get_current_output_name(stream); + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(&target_output.name); + send_command(stream, &focus_cmd); + + let focused_workspace_index = get_current_workspace(stream).num; + + let mut focus_cmd: String = "workspace ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(¤t_output_name); + send_command(stream, &focus_cmd); + + let mut focus_cmd: String = "move container to workspace ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(&target_output.name); + send_command(stream, &focus_cmd); + + let mut focus_cmd: String = "workspace ".to_string(); + focus_cmd.push_str(&focused_workspace_index.to_string()); + send_command(stream, &focus_cmd); + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(¤t_output_name); + send_command(stream, &focus_cmd); + } + None => { + // Else, we send the container on the current output + let mut focus_cmd: String = "move container to workspace ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + } + }; + } + } +} + +fn focus_to_workspace(stream: &UnixStream, workspace_index: usize) { + if workspace_index < 10 { + let mut cmd: String = "workspace number ".to_string(); + let full_ws_name = format!("{}{}", get_current_output_index(stream), &workspace_index) + .parse::() + .unwrap(); + cmd.push_str(&full_ws_name.to_string()); + send_command(stream, &cmd); + } else { + focus_to_workspace_absolute(stream, workspace_index); + } +} + +fn focus_to_workspace_absolute(stream: &UnixStream, workspace_index: usize) { + let output_index = (workspace_index / 10) as usize; + let outputs = get_outputs(stream); + let workspaces = get_workspaces(stream); + + // If the workspace already exists + match workspaces.iter().find(|w| w.num == workspace_index) { + Some(_) => { + let mut focus_cmd: String = "workspace number ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + } + None => { + let target_group = workspace_index / 10; + let target_screen_index = match workspaces.iter().find(|w| w.num / 10 == target_group) { + // If other workspaces on the same group exists + Some(other_workspace) => Some( + outputs + .iter() + .enumerate() + .find(|i| i.1.name == other_workspace.output) + .unwrap() + .0, + ), + None => { + // Or if the targeted output is currently connected + if output_index < outputs.len() { + Some(output_index) + } else { + None + } + } + }; + + match target_screen_index { + // If we have to send it to another screen + Some(target_screen_index) => { + let target_output = &outputs[target_screen_index - 1]; + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(&target_output.name); + send_command(stream, &focus_cmd); + } + None => {} + }; + // Then we focus the workspace + let mut focus_cmd: String = "workspace number ".to_string(); + focus_cmd.push_str(&workspace_index.to_string()); + send_command(stream, &focus_cmd); + } + } +} + +fn focus_to_workspace_virtual_output(stream: &UnixStream, workspace_index: usize) { + let current_workspace_index: usize = get_current_workspace(stream).num; + let focused_output_index = current_workspace_index / 10; + + let mut cmd: String = "workspace number ".to_string(); + let full_ws_name = format!("{}{}", focused_output_index, &workspace_index) .parse::() .unwrap(); cmd.push_str(&full_ws_name.to_string()); send_command(stream, &cmd); } -fn focus_to_workspace(stream: &UnixStream, workspace_index: usize) { - let mut cmd: String = "workspace number ".to_string(); - let full_ws_name = format!("{}{}", get_current_output_index(stream), &workspace_index) - .parse::() - .unwrap(); - cmd.push_str(&full_ws_name.to_string()); - send_command(stream, &cmd); +fn focus_to_output(stream: &UnixStream, target_output_index: usize) { + let outputs = get_outputs(stream); + if target_output_index < outputs.len() { + let mut cmd: String = "focus output ".to_string(); + cmd.push_str(&outputs[target_output_index - 1].name); + send_command(stream, &cmd); + } else { + let current_workspace_index = get_current_workspace(stream).num; + let contextual_workspace_index = + current_workspace_index - (current_workspace_index / 10) * 10; + focus_to_workspace_virtual_output(stream, contextual_workspace_index); + } } fn focus_all_outputs_to_workspace(stream: &UnixStream, workspace_index: usize) { @@ -258,15 +445,12 @@ fn move_container_to_prev_output(stream: &UnixStream) { fn move_container_to_next_or_prev_output(stream: &UnixStream, go_to_prev: bool) { let outputs = get_outputs(stream); - let focused_output_index = match outputs.iter().position(|x| x.focused) { - Some(i) => i, - None => panic!("WTF! No focused output???"), - }; + let focused_output_index = get_current_output_index(stream); let target_output = if go_to_prev { - &outputs[(focused_output_index + outputs.len() - 1) % outputs.len()] + &outputs[(focused_output_index + outputs.len() - 1) % outputs.len() - 1] } else { - &outputs[(focused_output_index + 1) % outputs.len()] + &outputs[(focused_output_index + 1) % outputs.len() - 1] }; let workspaces = get_workspaces(stream); @@ -286,6 +470,42 @@ fn move_container_to_next_or_prev_output(stream: &UnixStream, go_to_prev: bool) send_command(stream, &cmd); } +fn move_container_to_next_group(stream: &UnixStream) { + move_container_to_next_or_prev_group(stream, false); +} + +fn move_container_to_prev_group(stream: &UnixStream) { + move_container_to_next_or_prev_group(stream, true); +} + +fn move_container_to_next_or_prev_group(stream: &UnixStream, go_to_prev: bool) { + let current_workspace_index: usize = get_current_workspace(stream).num; + let focused_group_index = current_workspace_index / 10; + + let outputs = get_outputs(stream); + if focused_group_index < outputs.len() { + let target_output = if go_to_prev { + &outputs[(focused_group_index - 1) - 1] + } else { + &outputs[(focused_group_index + 1) - 1] + }; + + let mut cmd: String = "focus output ".to_string(); + cmd.push_str(&target_output.name); + send_command(stream, &cmd); + } else { + let target_workspace = if go_to_prev { + current_workspace_index - 10 + } else { + current_workspace_index + 10 + }; + + let mut cmd: String = "workspace number ".to_string(); + cmd.push_str(&target_workspace.to_string()); + send_command(stream, &cmd); + }; +} + fn init_workspaces(stream: &UnixStream, workspace_index: usize) { let outputs = get_outputs(stream); @@ -313,7 +533,7 @@ fn rearrange_workspaces(stream: &UnixStream) { let output_index = workspace.num / 10; if output_index < outputs.len() { let mut move_cmd = move_cmd_prefix.clone(); - move_cmd.push_str(&outputs[output_index].name); + move_cmd.push_str(&outputs[output_index - 1].name); send_command(stream, &move_cmd); } } @@ -333,6 +553,9 @@ fn main() { Command::Focus(action) => { focus_to_workspace(&stream, action.index); } + Command::FocusOutput(action) => { + focus_to_output(&stream, action.index); + } Command::FocusAllOutputs(action) => { focus_all_outputs_to_workspace(&stream, action.index); } @@ -342,6 +565,12 @@ fn main() { Command::PrevOutput => { move_container_to_prev_output(&stream); } + Command::NextGroup => { + move_container_to_next_group(&stream); + } + Command::PrevGroup => { + move_container_to_prev_group(&stream); + } Command::RearrangeWorkspaces => { rearrange_workspaces(&stream); } From b6f81aa7bb2f1513bcb3a916279f6f72742ba667 Mon Sep 17 00:00:00 2001 From: Nabos Date: Wed, 17 Aug 2022 11:17:28 +0200 Subject: [PATCH 2/6] Finished workspace groups --- src/main.rs | 113 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 31 deletions(-) diff --git a/src/main.rs b/src/main.rs index 08319f5..994f140 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,17 +29,17 @@ struct Cli { #[derive(Subcommand, Debug)] enum Command { - #[clap(about = "Initialize the workspaces for all the outputs")] + #[clap(about = "Initialize the workspace groups for all the outputs")] Init(InitAction), - #[clap(about = "Move the focused container to another workspace on the same output")] + #[clap(about = "Move the focused container to another workspace on the same workspace group")] Move(MoveAction), - #[clap(about = "Focus to another workspace on the same output")] + #[clap(about = "Focus to another workspace on the same workspace group")] Focus(FocusAction), - #[clap(about = "Focus to output")] - FocusOutput(FocusAction), + #[clap(about = "Focus to workspace group")] + FocusGroup(FocusAction), #[clap(about = "Focus to another workspace on all the outputs")] FocusAllOutputs(FocusAction), @@ -231,12 +231,7 @@ fn get_current_workspace(stream: &UnixStream) -> Workspace { fn move_container_to_workspace(stream: &UnixStream, workspace_index: usize) { if workspace_index < 10 { - let mut cmd: String = "move container to workspace number ".to_string(); - let full_ws_name = format!("{}{}", get_current_output_index(stream), workspace_index) - .parse::() - .unwrap(); - cmd.push_str(&full_ws_name.to_string()); - send_command(stream, &cmd); + move_container_to_workspace_relative(stream, workspace_index); } else { move_container_to_workspace_absolute(stream, workspace_index); } @@ -324,14 +319,21 @@ fn move_container_to_workspace_absolute(stream: &UnixStream, workspace_index: us } } +fn move_container_to_workspace_relative(stream: &UnixStream, workspace_index: usize) { + let current_workspace_index: usize = get_current_workspace(stream).num; + let focused_output_index = current_workspace_index / 10; + + let mut cmd: String = "move container to workspace number ".to_string(); + let full_ws_name = format!("{}{}", focused_output_index, workspace_index) + .parse::() + .unwrap(); + cmd.push_str(&full_ws_name.to_string()); + send_command(stream, &cmd); +} + fn focus_to_workspace(stream: &UnixStream, workspace_index: usize) { if workspace_index < 10 { - let mut cmd: String = "workspace number ".to_string(); - let full_ws_name = format!("{}{}", get_current_output_index(stream), &workspace_index) - .parse::() - .unwrap(); - cmd.push_str(&full_ws_name.to_string()); - send_command(stream, &cmd); + focus_to_workspace_relative(stream, workspace_index); } else { focus_to_workspace_absolute(stream, workspace_index); } @@ -390,7 +392,7 @@ fn focus_to_workspace_absolute(stream: &UnixStream, workspace_index: usize) { } } -fn focus_to_workspace_virtual_output(stream: &UnixStream, workspace_index: usize) { +fn focus_to_workspace_relative(stream: &UnixStream, workspace_index: usize) { let current_workspace_index: usize = get_current_workspace(stream).num; let focused_output_index = current_workspace_index / 10; @@ -402,17 +404,60 @@ fn focus_to_workspace_virtual_output(stream: &UnixStream, workspace_index: usize send_command(stream, &cmd); } -fn focus_to_output(stream: &UnixStream, target_output_index: usize) { +fn focus_to_group(stream: &UnixStream, group_index: usize) { let outputs = get_outputs(stream); - if target_output_index < outputs.len() { - let mut cmd: String = "focus output ".to_string(); - cmd.push_str(&outputs[target_output_index - 1].name); - send_command(stream, &cmd); - } else { - let current_workspace_index = get_current_workspace(stream).num; - let contextual_workspace_index = - current_workspace_index - (current_workspace_index / 10) * 10; - focus_to_workspace_virtual_output(stream, contextual_workspace_index); + let workspaces = get_workspaces(stream); + + let current_workspace_index: usize = get_current_workspace(stream).num; + let contextual_target_workspace_index = + current_workspace_index - (current_workspace_index / 10) * 10; + + let target_workspace_index = group_index * 10 + contextual_target_workspace_index; + + // If the workspace already exists + match workspaces.iter().find(|w| w.num == target_workspace_index) { + Some(_) => { + let mut focus_cmd: String = "workspace number ".to_string(); + focus_cmd.push_str(&target_workspace_index.to_string()); + send_command(stream, &focus_cmd); + } + None => { + let target_screen_index = match workspaces.iter().find(|w| w.num / 10 == group_index) { + // If other workspaces on the same group exists + Some(other_workspace) => Some( + outputs + .iter() + .enumerate() + .find(|i| i.1.name == other_workspace.output) + .unwrap() + .0, + ), + None => { + // Or if the targeted output is currently connected + if group_index < outputs.len() { + Some(group_index) + } else { + None + } + } + }; + + match target_screen_index { + // If we have to send it to another screen + Some(target_screen_index) => { + let target_output = &outputs[target_screen_index]; + + let mut focus_cmd: String = "focus output ".to_string(); + focus_cmd.push_str(&target_output.name); + send_command(stream, &focus_cmd); + } + None => {} + }; + // Then we focus the workspace + let mut focus_cmd: String = "workspace number ".to_string(); + focus_cmd.push_str(&target_workspace_index.to_string()); + send_command(stream, &focus_cmd); + } } } @@ -515,7 +560,13 @@ fn init_workspaces(stream: &UnixStream, workspace_index: usize) { cmd.push_str(output.name.as_str()); println!("{:?}", cmd.clone()); send_command(stream, &cmd); - focus_to_workspace(stream, workspace_index); + + let mut cmd: String = "workspace number ".to_string(); + let full_ws_name = format!("{}{}", get_current_output_index(stream), &workspace_index) + .parse::() + .unwrap(); + cmd.push_str(&full_ws_name.to_string()); + send_command(stream, &cmd); } } @@ -553,8 +604,8 @@ fn main() { Command::Focus(action) => { focus_to_workspace(&stream, action.index); } - Command::FocusOutput(action) => { - focus_to_output(&stream, action.index); + Command::FocusGroup(action) => { + focus_to_group(&stream, action.index); } Command::FocusAllOutputs(action) => { focus_all_outputs_to_workspace(&stream, action.index); From 72c34cb5e583639159a1094a5c1ca69ac470d309 Mon Sep 17 00:00:00 2001 From: Nabos Date: Wed, 17 Aug 2022 14:14:48 +0200 Subject: [PATCH 3/6] Fix focus next/prev group --- src/main.rs | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 994f140..658a4be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -515,39 +515,22 @@ fn move_container_to_next_or_prev_output(stream: &UnixStream, go_to_prev: bool) send_command(stream, &cmd); } -fn move_container_to_next_group(stream: &UnixStream) { - move_container_to_next_or_prev_group(stream, false); +fn focus_container_to_next_group(stream: &UnixStream) { + focus_container_to_next_or_prev_group(stream, false); } -fn move_container_to_prev_group(stream: &UnixStream) { - move_container_to_next_or_prev_group(stream, true); +fn focus_container_to_prev_group(stream: &UnixStream) { + focus_container_to_next_or_prev_group(stream, true); } -fn move_container_to_next_or_prev_group(stream: &UnixStream, go_to_prev: bool) { +fn focus_container_to_next_or_prev_group(stream: &UnixStream, go_to_prev: bool) { let current_workspace_index: usize = get_current_workspace(stream).num; let focused_group_index = current_workspace_index / 10; - let outputs = get_outputs(stream); - if focused_group_index < outputs.len() { - let target_output = if go_to_prev { - &outputs[(focused_group_index - 1) - 1] - } else { - &outputs[(focused_group_index + 1) - 1] - }; - - let mut cmd: String = "focus output ".to_string(); - cmd.push_str(&target_output.name); - send_command(stream, &cmd); + if go_to_prev { + focus_to_group(stream, focused_group_index - 1); } else { - let target_workspace = if go_to_prev { - current_workspace_index - 10 - } else { - current_workspace_index + 10 - }; - - let mut cmd: String = "workspace number ".to_string(); - cmd.push_str(&target_workspace.to_string()); - send_command(stream, &cmd); + focus_to_group(stream, focused_group_index + 1); }; } @@ -617,10 +600,10 @@ fn main() { move_container_to_prev_output(&stream); } Command::NextGroup => { - move_container_to_next_group(&stream); + focus_container_to_next_group(&stream); } Command::PrevGroup => { - move_container_to_prev_group(&stream); + focus_container_to_prev_group(&stream); } Command::RearrangeWorkspaces => { rearrange_workspaces(&stream); From 4ec989ed72a447caeeef6677d8f909f6edb6705e Mon Sep 17 00:00:00 2001 From: Nabos Date: Tue, 23 Aug 2022 15:14:19 +0200 Subject: [PATCH 4/6] Fix focus to group when no existing workspace --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 658a4be..8c1f3bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -434,7 +434,7 @@ fn focus_to_group(stream: &UnixStream, group_index: usize) { ), None => { // Or if the targeted output is currently connected - if group_index < outputs.len() { + if group_index <= outputs.len() { Some(group_index) } else { None @@ -445,7 +445,7 @@ fn focus_to_group(stream: &UnixStream, group_index: usize) { match target_screen_index { // If we have to send it to another screen Some(target_screen_index) => { - let target_output = &outputs[target_screen_index]; + let target_output = &outputs[target_screen_index - 1]; let mut focus_cmd: String = "focus output ".to_string(); focus_cmd.push_str(&target_output.name); @@ -565,7 +565,7 @@ fn rearrange_workspaces(stream: &UnixStream) { send_command(stream, &focus_cmd); let output_index = workspace.num / 10; - if output_index < outputs.len() { + if output_index <= outputs.len() { let mut move_cmd = move_cmd_prefix.clone(); move_cmd.push_str(&outputs[output_index - 1].name); send_command(stream, &move_cmd); From 4620e8ab2c2b35dad092dac4e36656a648d0fccb Mon Sep 17 00:00:00 2001 From: Nabos Date: Thu, 25 Aug 2022 15:25:32 +0200 Subject: [PATCH 5/6] Fix focus to group when already existing group --- src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 8c1f3bd..047b4da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -430,7 +430,8 @@ fn focus_to_group(stream: &UnixStream, group_index: usize) { .enumerate() .find(|i| i.1.name == other_workspace.output) .unwrap() - .0, + .0 + + 1, ), None => { // Or if the targeted output is currently connected From 1c8ab4246a494f1d0b0bd0542f11092eacaf3d66 Mon Sep 17 00:00:00 2001 From: Nabos Date: Fri, 23 Dec 2022 09:59:06 +0100 Subject: [PATCH 6/6] Fix minimum output index --- src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 047b4da..c58f5fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -566,9 +566,9 @@ fn rearrange_workspaces(stream: &UnixStream) { send_command(stream, &focus_cmd); let output_index = workspace.num / 10; - if output_index <= outputs.len() { + if output_index <= outputs.len() - 1 { let mut move_cmd = move_cmd_prefix.clone(); - move_cmd.push_str(&outputs[output_index - 1].name); + move_cmd.push_str(&outputs[output_index.max(1) - 1].name); send_command(stream, &move_cmd); } }