use anyhow::Result;
use crate::db::entities::OutputEntity;
use crate::db::DatabaseManager;
use crate::sway::SwayIpcClient;
pub struct VisibilityService {
db: DatabaseManager,
ipc_client: SwayIpcClient,
}
impl VisibilityService {
pub fn new(db: DatabaseManager, ipc_client: SwayIpcClient) -> Self {
Self { db, ipc_client }
}
pub fn with_config(
db: DatabaseManager,
ipc_client: SwayIpcClient,
_config: &sway_groups_config::SwaygConfig,
) -> Self {
Self { db, ipc_client }
}
pub async fn get_visible(&self, output_name: &str) -> Result<Vec<String>> {
let active_group = self.resolve_active_group(output_name).await?;
let sway_workspaces = self.ipc_client.get_workspaces()?;
let sway_names: Vec<String> = sway_workspaces
.iter()
.filter(|w| w.output == output_name)
.map(|w| w.name.clone())
.collect();
Ok(
crate::db::queries::compute_visible_workspaces(
self.db.conn(),
&sway_names,
active_group.as_deref(),
)
.await?,
)
}
pub async fn get_visible_global(&self) -> Result<Vec<String>> {
let outputs = self.ipc_client.get_outputs()?;
let mut all = Vec::new();
for output in outputs {
let visible = self.get_visible(&output.name).await?;
all.extend(visible);
}
all.sort();
all.dedup();
Ok(all)
}
pub async fn get_visible_for_group(
&self,
_output_name: &str,
active_group: &str,
) -> Result<Vec<String>> {
let sway_workspaces = self.ipc_client.get_workspaces()?;
let sway_names: Vec<String> = sway_workspaces.iter().map(|w| w.name.clone()).collect();
Ok(
crate::db::queries::compute_visible_workspaces(
self.db.conn(),
&sway_names,
Some(active_group),
)
.await?,
)
}
async fn resolve_active_group(&self, output_name: &str) -> Result<Option<String>> {
Ok(OutputEntity::find_by_name(output_name)
.one(self.db.conn())
.await?
.map(|o| o.active_group)
.unwrap_or(None))
}
}