From 86f26f94277839142e0e0083013638be48d071f7 Mon Sep 17 00:00:00 2001 From: John Axel Eriksson Date: Thu, 9 Mar 2023 23:56:14 +0100 Subject: [PATCH 1/2] Don't query sway unnecessarily, clean up a bit --- src/layout.rs | 2 +- .../command_handlers/layout/stack_main.rs | 22 ++++--- src/server/event_handlers/layout/spiral.rs | 33 +++++----- .../event_handlers/layout/stack_main.rs | 61 +++++++++---------- .../event_handlers/misc/window_focus.rs | 2 +- .../event_handlers/misc/workspace_renamer.rs | 2 +- src/server/message_handler.rs | 4 +- src/utils.rs | 17 +++--- 8 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index c5daba5..9ce5c7e 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -27,7 +27,7 @@ impl Display for WorkspaceLayout { let string_layout = match self { Self::Spiral => String::from("spiral"), Self::StackMain { stack_layout, size } => { - format!("stack_main {} {}", stack_layout, size) + format!("stack_main {stack_layout} {size}") } Self::Manual => String::from("manual"), }; diff --git a/src/server/command_handlers/layout/stack_main.rs b/src/server/command_handlers/layout/stack_main.rs index 4137bf7..2771576 100644 --- a/src/server/command_handlers/layout/stack_main.rs +++ b/src/server/command_handlers/layout/stack_main.rs @@ -49,7 +49,7 @@ impl StackMain { for node in stack_iter.cycle() { if prev_was_focused { - let cmd = format!("[con_id={}] focus;", node.id); + let cmd = format!("[con_id={node_id}] focus;", node_id = node.id); log::debug!("stack main controller, stack focus prev: {}", cmd); self.connection.run_command(cmd).await?; return Ok(()); @@ -88,17 +88,18 @@ impl StackMain { for node in stack_leaves { if let Some(next) = stack_leaves_next.next() { cmd.push_str(&format!( - "[con_id={}] focus; swap container with con_id {}; ", - node.id, next.id + "[con_id={node_id}] focus; swap container with con_id {next_id}; ", + node_id = node.id, + next_id = next.id )); } else { break; } } cmd.push_str(&format!( - "[con_id={}] focus; [con_id={}] focus; ", - stack.nodes.last().unwrap().id, - main.id + "[con_id={last_stack_id}] focus; [con_id={main_id}] focus; ", + last_stack_id = stack.nodes.last().unwrap().id, + main_id = main.id )); log::debug!("stack main controller, master cycle next 1: {}", cmd); self.connection.run_command(cmd).await?; @@ -118,8 +119,8 @@ impl StackMain { .unwrap(); let cmd = format!( - "[con_id={}] focus; swap container with con_id {}; [con_id={}] focus", - main.id, stack_first, stack_first, + "[con_id={main_id}] focus; swap container with con_id {stack_first}; [con_id={stack_first}] focus", + main_id = main.id ); log::debug!("stack main controller, master cycle next 2: {}", cmd); self.connection.run_command(cmd).await?; @@ -155,8 +156,9 @@ impl StackMain { }; let cmd = format!( - "[con_id={}] focus; swap container with con_id {}; [con_id={}] focus", - main.id, stack_current.id, stack_current.id + "[con_id={main_id}] focus; swap container with con_id {stack_current_id}; [con_id={stack_current_id}] focus", + main_id = main.id, + stack_current_id = stack_current.id ); log::debug!("stack main controller, swap visible: {}", cmd); self.connection.run_command(cmd).await?; diff --git a/src/server/event_handlers/layout/spiral.rs b/src/server/event_handlers/layout/spiral.rs index 2f6d78f..4daf134 100644 --- a/src/server/event_handlers/layout/spiral.rs +++ b/src/server/event_handlers/layout/spiral.rs @@ -21,27 +21,30 @@ impl Spiral { Ok(Self { connection }) } - async fn layout(&mut self, event: WindowEvent) -> Result<()> { + async fn on_window_focus(&mut self, event: WindowEvent) -> Result<()> { log::debug!("spiral manager handling event: {:?}", event.change); - let tree = self.connection.get_tree().await?; - let node = tree - .find_as_ref(|n| n.id == event.container.id) - .expect(&format!("no node found with id {}", event.container.id)); - let ws = node.get_workspace().await?; + let focused_node = &event.container; + let ws = focused_node.get_workspace().await?; if ws.name == utils::PERSWAY_TMP_WORKSPACE { log::debug!("skip spiral layout of tmp workspace"); return Ok(()); } - if !(node.is_floating_window() - || node.is_floating_container() - || node.is_full_screen() - || node.is_stacked().await? - || node.is_tabbed().await?) + if !(focused_node.is_floating_window() + || focused_node.is_floating_container() + || focused_node.is_full_screen() + || focused_node.is_stacked().await? + || focused_node.is_tabbed().await?) { - let cmd = if node.rect.height > node.rect.width { - format!("[con_id={}] focus; split v", node.id) + let cmd = if focused_node.rect.height > focused_node.rect.width { + format!( + "[con_id={focused_node_id}] focus; split v", + focused_node_id = focused_node.id + ) } else { - format!("[con_id={}] focus; split h", node.id) + format!( + "[con_id={focused_node_id}] focus; split h", + focused_node_id = focused_node.id + ) }; log::debug!("spiral layout: {}", cmd); self.connection.run_command(cmd).await?; @@ -55,7 +58,7 @@ impl WindowEventHandler for Spiral { async fn handle(&mut self, event: Box) { match event.change { WindowChange::Focus => { - if let Err(e) = self.layout(*event).await { + if let Err(e) = self.on_window_focus(*event).await { log::error!("spiral manager, layout err: {}", e); }; } diff --git a/src/server/event_handlers/layout/stack_main.rs b/src/server/event_handlers/layout/stack_main.rs index 3703f0e..1c82a51 100644 --- a/src/server/event_handlers/layout/stack_main.rs +++ b/src/server/event_handlers/layout/stack_main.rs @@ -34,16 +34,14 @@ impl StackMain { async fn on_new_window(&mut self, event: &WindowEvent) -> Result<()> { let tree = self.connection.get_tree().await?; - let node = tree - .find_as_ref(|n| n.id == event.container.id) - .expect(&format!("no node found with id {}", event.container.id)); - let ws = node.get_workspace().await?; + let new_node = &event.container; + let ws = new_node.get_workspace().await?; if ws.name == utils::PERSWAY_TMP_WORKSPACE { log::debug!("skip stack_main layout of tmp workspace"); return Ok(()); } let wstree = tree.find_as_ref(|n| n.id == ws.id).unwrap(); - log::debug!("new_window id: {}", event.container.id); + log::debug!("new window id: {}", new_node.id); log::debug!("workspace nodes len: {}", wstree.nodes.len()); let layout = match self.stack_layout { StackLayout::Tabbed => "split v; layout tabbed", @@ -52,7 +50,10 @@ impl StackMain { }; match wstree.nodes.len() { 1 => { - let cmd = format!("[con_id={}] focus; split h", event.container.id); + let cmd = format!( + "[con_id={new_node_id}] focus; split h", + new_node_id = new_node.id + ); self.connection.run_command(cmd).await?; Ok(()) } @@ -62,20 +63,20 @@ impl StackMain { let cmd = if stack.is_window() { format!( - "[con_id={}] focus; {}; resize set width {}; [con_id={}] focus", - stack.id, - layout, - (100 - self.size), - main.id + "[con_id={stack_id}] focus; {layout}; [con_id={main_id}] focus; resize set width {main_width};", + stack_id = stack.id, + main_id = main.id, + main_width = self.size, ) } else { - if let Some(node) = stack.find_as_ref(|n| n.id == event.container.id) { + if stack.find_as_ref(|n| n.id == new_node.id).is_some() { format!( - "[con_id={}] focus; swap container with con_id {}; [con_id={}] focus", - main.id, node.id, node.id + "[con_id={main_id}] focus; swap container with con_id {new_node_id}; [con_id={new_node_id}] focus", + main_id = main.id, + new_node_id = new_node.id ) } else { - String::from("nop event container not in stack") + String::from("nop new node not in stack") } }; @@ -87,17 +88,16 @@ impl StackMain { .nodes .iter() .skip(1) - .find(|n| n.is_window() && n.id != event.container.id) + .find(|n| n.is_window() && n.id != new_node.id) .expect("main window not found"); let stack = wstree.nodes.first().expect("stack container not found"); let stack_mark = format!("_stack_{}", stack.id); let cmd = format!( - "[con_id={}] mark --add {}; [con_id={}] focus; move container to mark {}; [con_mark={}] unmark {}; [con_id={}] focus; swap container with con_id {}; [con_id={}] focus", - stack.id, stack_mark, - event.container.id, stack_mark, - stack_mark, stack_mark, - main.id, event.container.id, event.container.id + "[con_id={stack_id}] mark --add {stack_mark}; [con_id={new_node_id}] focus; move container to mark {stack_mark}; [con_mark={stack_mark}] unmark {stack_mark}; [con_id={main_id}] focus; swap container with con_id {new_node_id}; [con_id={new_node_id}] focus", + stack_id = stack.id, + main_id = main.id, + new_node_id = new_node.id ); log::debug!("new_window: {}", cmd); @@ -110,6 +110,7 @@ impl StackMain { } async fn on_close_window(&mut self, event: &WindowEvent) -> Result<()> { let tree = self.connection.get_tree().await?; + let closed_node = &event.container; let ws = get_focused_workspace(&mut self.connection).await?; if ws.name == utils::PERSWAY_TMP_WORKSPACE { log::debug!("skip stack_main layout of tmp workspace"); @@ -121,7 +122,7 @@ impl StackMain { if let Some(stack) = wstree .nodes .iter() - .filter(|n| n.id != event.container.id) + .filter(|n| n.id != closed_node.id) .next() { let stack_current = stack @@ -135,8 +136,8 @@ impl StackMain { let cmd = if wstree.iter().filter(|n| n.is_window()).count() == 1 { log::debug!("on_close_window, count 1, stack_id: {}", stack_current.id); format!( - "[con_id={}] focus; layout splith; move up", - stack_current.id + "[con_id={stack_focused_id}] focus; layout splith; move up", + stack_focused_id = stack_current.id ) } else { log::debug!( @@ -144,8 +145,9 @@ impl StackMain { stack_current.id ); format!( - "[con_id={}] focus; move right; resize set width {}", - stack_current.id, self.size + "[con_id={stack_current_id}] focus; move right; resize set width {main_width}", + stack_current_id = stack_current.id, + main_width = self.size ) }; log::debug!("close_window: {}", cmd); @@ -155,11 +157,8 @@ impl StackMain { Ok(()) } async fn on_move_window(&mut self, event: &WindowEvent) -> Result<()> { - let tree = self.connection.get_tree().await?; - let node = tree - .find_as_ref(|n| n.id == event.container.id) - .expect(&format!("no node found with id {}", event.container.id)); - let ws = node.get_workspace().await?; + let moved_node = &event.container; + let ws = moved_node.get_workspace().await?; if ws.name == utils::PERSWAY_TMP_WORKSPACE { log::debug!("skip stack_main layout of tmp workspace"); return Ok(()); diff --git a/src/server/event_handlers/misc/window_focus.rs b/src/server/event_handlers/misc/window_focus.rs index 1691867..1a10929 100644 --- a/src/server/event_handlers/misc/window_focus.rs +++ b/src/server/event_handlers/misc/window_focus.rs @@ -46,7 +46,7 @@ impl WindowFocus { if let Some(window_focus_leave_cmd) = &self.window_focus_leave_cmd { if let Some(id) = self.previously_focused_id { self.connection - .run_command(format!("[con_id={id}] {}", window_focus_leave_cmd)) + .run_command(format!("[con_id={id}] {window_focus_leave_cmd}")) .await?; } } diff --git a/src/server/event_handlers/misc/workspace_renamer.rs b/src/server/event_handlers/misc/workspace_renamer.rs index 52f036c..d9c5436 100644 --- a/src/server/event_handlers/misc/workspace_renamer.rs +++ b/src/server/event_handlers/misc/workspace_renamer.rs @@ -67,7 +67,7 @@ impl WorkspaceRenamer { .next() .unwrap_or(&focused_ws.name); if let Some(app_name) = get_app_name(&event) { - let cmd = format!("rename workspace to {}: {}", ws_num, app_name); + let cmd = format!("rename workspace to {ws_num}: {app_name}"); log::debug!("workspace name manager, cmd: {}", cmd); self.connection.run_command(cmd).await?; } else { diff --git a/src/server/message_handler.rs b/src/server/message_handler.rs index 179a28d..66ca9f1 100644 --- a/src/server/message_handler.rs +++ b/src/server/message_handler.rs @@ -100,8 +100,8 @@ impl MessageHandler { |mut conn, ws_num, _old_ws_id, _output_id, windows| async move { for window in windows.iter().rev() { let cmd = format!( - "[con_id={}] move to workspace number {}; [con_id={}] focus", - window.id, ws_num, window.id + "[con_id={window_id}] move to workspace number {ws_num}; [con_id={window_id}] focus", + window_id = window.id ); log::debug!("relayout closure cmd: {}", cmd); conn.run_command(cmd).await?; diff --git a/src/utils.rs b/src/utils.rs index ac65894..5c71a89 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -64,21 +64,21 @@ where for window in ws.iter().filter(|n| n.is_window()) { windows.push(window.clone()); cmd.push_str(&format!( - "[con_id={}] move to workspace {}; ", - window.id, PERSWAY_TMP_WORKSPACE + "[con_id={window_id}] move to workspace {PERSWAY_TMP_WORKSPACE}; ", + window_id = window.id )); } cmd.push_str(&format!( - "workspace {}; move workspace to output {}; ", - PERSWAY_TMP_WORKSPACE, output.id + "workspace {PERSWAY_TMP_WORKSPACE}; move workspace to output {output_id}; ", + output_id = output.id )); log::debug!("relayout before layout closure: {}", cmd); connection.run_command(cmd).await?; task::sleep(Duration::from_millis(25)).await; let mut cmd = String::from(""); cmd.push_str(&format!( - "workspace {}; move workspace to output {}; ", - ws_num, output.id + "workspace {ws_num}; move workspace to output {output_id}; ", + output_id = output.id )); log::debug!("relayout before layout closure: {}", cmd); connection.run_command(cmd).await?; @@ -93,8 +93,9 @@ where .context("no focused workspace")?; if &focused_workspace_after_closure.num != &focused_workspace.num { let cmd = format!( - "workspace number {}; move workspace to output {}; ", - &focused_workspace.num, output.id + "workspace number {focused_ws_num}; move workspace to output {output_id}; ", + focused_ws_num = &focused_workspace.num, + output_id = output.id ); log::debug!("relayout after layout closure: {}", cmd); connection.run_command(cmd).await?; From cb16dddf7abb032cbcfa80eb067d2e9a83297470 Mon Sep 17 00:00:00 2001 From: John Axel Eriksson Date: Mon, 13 Mar 2023 16:31:29 +0100 Subject: [PATCH 2/2] Fixes #42 - remember workspace name on relayout. Also increase wait between window placements. This is because relayout sometimes doesn't result in the expected layout. It's really quite an ugly way to do this but it simplifies other things. --- src/server/message_handler.rs | 2 +- src/utils.rs | 36 +++++++++++++++++------------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/server/message_handler.rs b/src/server/message_handler.rs index 66ca9f1..6dc6588 100644 --- a/src/server/message_handler.rs +++ b/src/server/message_handler.rs @@ -105,7 +105,7 @@ impl MessageHandler { ); log::debug!("relayout closure cmd: {}", cmd); conn.run_command(cmd).await?; - task::sleep(Duration::from_millis(25)).await; + task::sleep(Duration::from_millis(50)).await; } Ok(()) }, diff --git a/src/utils.rs b/src/utils.rs index 5c71a89..1b57445 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -74,33 +74,31 @@ where )); log::debug!("relayout before layout closure: {}", cmd); connection.run_command(cmd).await?; - task::sleep(Duration::from_millis(25)).await; - let mut cmd = String::from(""); - cmd.push_str(&format!( - "workspace {ws_num}; move workspace to output {output_id}; ", - output_id = output.id - )); - log::debug!("relayout before layout closure: {}", cmd); - connection.run_command(cmd).await?; - task::sleep(Duration::from_millis(25)).await; + task::sleep(Duration::from_millis(50)).await; let closure_conn = Connection::new().await?; f(closure_conn, ws_num, ws.id, output.id, windows).await?; - task::sleep(Duration::from_millis(25)).await; + task::sleep(Duration::from_millis(50)).await; let workspaces = connection.get_workspaces().await?; let focused_workspace_after_closure = workspaces .iter() .find(|w| w.focused) .context("no focused workspace")?; + let mut cmd = String::new(); if &focused_workspace_after_closure.num != &focused_workspace.num { - let cmd = format!( - "workspace number {focused_ws_num}; move workspace to output {output_id}; ", - focused_ws_num = &focused_workspace.num, - output_id = output.id - ); - log::debug!("relayout after layout closure: {}", cmd); - connection.run_command(cmd).await?; - } else { - log::debug!("skip relayout after layout closure"); + cmd.push_str(&format!( + "workspace number {focused_workspace_num}; move workspace to output {output_id}; ", + focused_workspace_num = &focused_workspace.num, + output_id = output.id, + )); } + cmd.push_str(&format!( + "rename workspace to {ws_name}", + ws_name = focused_workspace.name + )); + log::debug!( + "rename new workspace to old name after layout closure: {}", + cmd + ); + connection.run_command(cmd).await?; Ok(()) }