2023-08-24 21:18:07 -05:00
|
|
|
use super::{Visibility, Workspace, WorkspaceClient, WorkspaceUpdate};
|
2024-08-05 09:22:01 -03:00
|
|
|
use crate::{await_sync, send};
|
|
|
|
use color_eyre::Result;
|
|
|
|
use swayipc_async::{Node, WorkspaceChange, WorkspaceEvent};
|
|
|
|
use tokio::sync::broadcast::{channel, Receiver};
|
2023-01-27 20:08:14 +00:00
|
|
|
|
2024-08-05 09:22:01 -03:00
|
|
|
use crate::clients::sway::Client;
|
2023-01-27 20:08:14 +00:00
|
|
|
|
2024-01-07 23:50:10 +00:00
|
|
|
impl WorkspaceClient for Client {
|
|
|
|
fn focus(&self, id: String) -> Result<()> {
|
2023-01-27 20:08:14 +00:00
|
|
|
await_sync(async move {
|
2024-08-05 09:22:01 -03:00
|
|
|
let mut client = self.connection().lock().await;
|
2023-01-27 20:08:14 +00:00
|
|
|
client.run_command(format!("workspace {id}")).await
|
|
|
|
})?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn subscribe_workspace_change(&self) -> Receiver<WorkspaceUpdate> {
|
2024-08-05 09:22:01 -03:00
|
|
|
let (tx, rx) = channel(16);
|
2023-01-27 20:08:14 +00:00
|
|
|
|
2024-08-05 09:22:01 -03:00
|
|
|
let client = self.connection().clone();
|
2024-01-07 23:50:10 +00:00
|
|
|
|
2024-08-05 09:22:01 -03:00
|
|
|
await_sync(async {
|
|
|
|
let mut client = client.lock().await;
|
|
|
|
let workspaces = client.get_workspaces().await.expect("to get workspaces");
|
2023-01-27 20:08:14 +00:00
|
|
|
|
2024-08-05 09:22:01 -03:00
|
|
|
let event =
|
|
|
|
WorkspaceUpdate::Init(workspaces.into_iter().map(Workspace::from).collect());
|
2023-01-27 20:08:14 +00:00
|
|
|
|
2024-08-05 09:22:01 -03:00
|
|
|
send!(tx, event);
|
|
|
|
|
|
|
|
drop(client);
|
|
|
|
|
|
|
|
self.add_listener::<swayipc_async::WorkspaceEvent>(move |event| {
|
|
|
|
let update = WorkspaceUpdate::from(event.clone());
|
|
|
|
send!(tx, update);
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
.expect("to add listener");
|
|
|
|
});
|
2023-01-27 20:08:14 +00:00
|
|
|
|
|
|
|
rx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Node> for Workspace {
|
|
|
|
fn from(node: Node) -> Self {
|
2023-08-24 21:18:07 -05:00
|
|
|
let visibility = Visibility::from(&node);
|
|
|
|
|
2023-01-27 20:08:14 +00:00
|
|
|
Self {
|
2024-05-09 17:25:08 +01:00
|
|
|
id: node.id,
|
2023-01-27 20:08:14 +00:00
|
|
|
name: node.name.unwrap_or_default(),
|
|
|
|
monitor: node.output.unwrap_or_default(),
|
2023-08-24 21:18:07 -05:00
|
|
|
visibility,
|
2023-01-27 20:08:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<swayipc_async::Workspace> for Workspace {
|
|
|
|
fn from(workspace: swayipc_async::Workspace) -> Self {
|
2023-08-24 21:18:07 -05:00
|
|
|
let visibility = Visibility::from(&workspace);
|
|
|
|
|
2023-01-27 20:08:14 +00:00
|
|
|
Self {
|
2024-05-09 17:25:08 +01:00
|
|
|
id: workspace.id,
|
2023-01-27 20:08:14 +00:00
|
|
|
name: workspace.name,
|
|
|
|
monitor: workspace.output,
|
2023-08-24 21:18:07 -05:00
|
|
|
visibility,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&Node> for Visibility {
|
|
|
|
fn from(node: &Node) -> Self {
|
|
|
|
if node.focused {
|
|
|
|
Self::focused()
|
|
|
|
} else if node.visible.unwrap_or(false) {
|
|
|
|
Self::visible()
|
|
|
|
} else {
|
|
|
|
Self::Hidden
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&swayipc_async::Workspace> for Visibility {
|
|
|
|
fn from(workspace: &swayipc_async::Workspace) -> Self {
|
|
|
|
if workspace.focused {
|
|
|
|
Self::focused()
|
|
|
|
} else if workspace.visible {
|
|
|
|
Self::visible()
|
|
|
|
} else {
|
|
|
|
Self::Hidden
|
2023-01-27 20:08:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<WorkspaceEvent> for WorkspaceUpdate {
|
|
|
|
fn from(event: WorkspaceEvent) -> Self {
|
|
|
|
match event.change {
|
|
|
|
WorkspaceChange::Init => {
|
|
|
|
Self::Add(event.current.expect("Missing current workspace").into())
|
|
|
|
}
|
2024-05-09 17:25:08 +01:00
|
|
|
WorkspaceChange::Empty => {
|
|
|
|
Self::Remove(event.current.expect("Missing current workspace").id)
|
|
|
|
}
|
2023-01-27 20:08:14 +00:00
|
|
|
WorkspaceChange::Focus => Self::Focus {
|
2023-08-24 21:18:07 -05:00
|
|
|
old: event.old.map(Workspace::from),
|
|
|
|
new: Workspace::from(event.current.expect("Missing current workspace")),
|
2023-01-27 20:08:14 +00:00
|
|
|
},
|
|
|
|
WorkspaceChange::Move => {
|
|
|
|
Self::Move(event.current.expect("Missing current workspace").into())
|
|
|
|
}
|
2024-09-25 22:38:14 -03:00
|
|
|
WorkspaceChange::Urgent => {
|
|
|
|
if let Some(node) = event.current {
|
|
|
|
Self::Urgent {
|
|
|
|
id: node.id,
|
|
|
|
urgent: node.urgent,
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Self::Unknown
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 00:43:36 +00:00
|
|
|
_ => Self::Unknown,
|
2023-01-27 20:08:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|