sway_workspace_manager/
lib.rs1use swayipc::{Connection, Event, EventType, WorkspaceChange};
2
3mod command;
4mod workspaces;
5
6pub use command::{Command, Position};
7pub use workspaces::{OrderedWorkspaces, Workspaces};
8
9fn process_event(
10 connection: &mut Connection,
11 event: Result<Event, swayipc::Error>,
12) -> Result<(), swayipc::Error> {
13 if let Event::Workspace(event) = event? {
14 if event.change == WorkspaceChange::Empty {
15 Workspaces::get(connection)?.reorder(connection)?;
16 }
17 }
18
19 Ok(())
20}
21
22pub fn run(
23 connection: &mut Connection,
24 mut workspaces: OrderedWorkspaces,
25 command: Command,
26) -> Result<(), swayipc::Error> {
27 let num_workspaces = workspaces.names().len() - 1;
28
29 match command {
30 Command::Reorder { daemon: false } => (),
31 Command::Reorder { daemon: true } => {
32 for event in Connection::new()?.subscribe([EventType::Workspace])? {
34 let result = process_event(connection, event);
35
36 if let Err(err) = result {
37 eprintln!("{err}");
38 }
39 }
40 }
41
42 Command::Switch { target, carry } => {
43 let target_index = target.num_existing(workspaces.current_index(), num_workspaces)?;
44 let target_name = workspaces.name(target_index);
45
46 if carry {
47 connection.run_command(format!(
49 "move container to workspace \"{target_index}{target_name}\""
50 ))?;
51 }
52
53 connection.run_command(format!("workspace \"{target_index}{target_name}\""))?;
54
55 Workspaces::get(connection)?.reorder(connection)?;
56 }
57
58 Command::Create { target, carry } => {
59 let target_index = target.num_new(workspaces.current_index(), num_workspaces)?;
60
61 workspaces.insert(connection, target_index)?;
62
63 if carry {
64 connection
66 .run_command(format!("move container to workspace \"{target_index}\""))?;
67 }
68
69 connection.run_command(format!("workspace \"{target_index}\""))?;
70
71 Workspaces::get(connection)?.reorder(connection)?;
72 }
73
74 Command::Swap { target } => {
75 let current_index = workspaces.current_index();
76 let current_name = &workspaces.names()[current_index].as_ref().unwrap();
77
78 let target_index = target.num_existing(workspaces.current_index(), num_workspaces)?;
79 let target_name = &workspaces.names()[target_index].as_ref().unwrap();
80
81 connection.run_command(format!(
82 "rename workspace \"{target_index}{target_name}\" to a"
83 ))?;
84 connection.run_command(format!(
85 "rename workspace \"{current_index}{current_name}\" to \"{target_index}{current_name}\""
86 ))?;
87 connection.run_command(format!(
88 "rename workspace a to \"{current_index}{target_name}\""
89 ))?;
90 }
91
92 Command::Rename { new_name } => {
93 let current_index = workspaces.current_index();
94 let current_name = &workspaces.names()[current_index].as_ref().unwrap();
95
96 if !new_name.is_empty() {
97 connection.run_command(format!(
98 "rename workspace \"{current_index}{current_name}\" to \"{current_index}:{new_name}\""
99 ))?;
100 } else {
101 connection.run_command(format!(
102 "rename workspace \"{current_index}{current_name}\" to \"{current_index}\""
103 ))?;
104 }
105 }
106 }
107
108 Ok(())
109}