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 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();
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            .with_context(|| {
27                format!(
28                    "Failed to execute switch workspace with id {}",
29                    workspace_id
30                )
31            })?;
32    }
33    Ok(())
34}
35
36pub fn switch_client(address: &Address) -> anyhow::Result<()> {
37    trace!("execute switch to next_client: {}", address);
38    Dispatch::call(DispatchType::FocusWindow(WindowIdentifier::Address(
39        address.clone(),
40    )))?;
41    Dispatch::call(DispatchType::BringActiveToTop)?;
42    Ok(())
43}
44
45fn switch_normal_workspace(workspace_id: WorkspaceId) -> anyhow::Result<()> {
46    trace!("execute switch to workspace {workspace_id}");
47    Dispatch::call(DispatchType::Workspace(WorkspaceIdentifierWithSpecial::Id(
48        workspace_id,
49    )))?;
50    Ok(())
51}