hyprshell_exec_lib/
switch.rs

1use anyhow::Context;
2use hyprland::data::Workspace;
3use hyprland::dispatch::{
4    Dispatch, DispatchType, WindowIdentifier, WorkspaceIdentifierWithSpecial,
5};
6use hyprland::prelude::*;
7use hyprland::shared::{Address, WorkspaceId};
8use tracing::{trace, warn};
9
10pub async fn switch_workspace(workspace_id: WorkspaceId) -> anyhow::Result<()> {
11    // check if already on workspace (if so, don't switch because it throws an error `Previous workspace doesn't exist`)
12    let current_workspace = Workspace::get_active_async().await;
13    if let Ok(workspace) = current_workspace {
14        if workspace_id == workspace.id {
15            trace!("Already on workspace {}", workspace_id);
16            return Ok(());
17        }
18    }
19
20    if workspace_id < 0 {
21        warn!(
22            "Special workspace id detected, not switching to special workspace, TODO not supported"
23        );
24    } else {
25        switch_normal_workspace(workspace_id)
26            .await
27            .with_context(|| {
28                format!(
29                    "Failed to execute switch workspace with id {}",
30                    workspace_id
31                )
32            })?;
33    }
34    Ok(())
35}
36
37pub async fn switch_client(address: &Address) -> anyhow::Result<()> {
38    trace!("execute switch to next_client: {}", address);
39    Dispatch::call_async(DispatchType::FocusWindow(WindowIdentifier::Address(
40        address.clone(),
41    )))
42    .await?;
43    Dispatch::call_async(DispatchType::BringActiveToTop).await?;
44    Ok(())
45}
46
47async fn switch_normal_workspace(workspace_id: WorkspaceId) -> anyhow::Result<()> {
48    trace!("execute switch to workspace {workspace_id}");
49    Dispatch::call_async(DispatchType::Workspace(WorkspaceIdentifierWithSpecial::Id(
50        workspace_id,
51    )))
52    .await?;
53    Ok(())
54}