mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-02 03:01:04 +02:00
feat(workspaces): hyprland support
Resolves #18. The bar will now automatically detect whether running under Sway or Hyprland and use the correct IPC client depending.
This commit is contained in:
parent
a79900d842
commit
6e5d0c1e8c
8 changed files with 585 additions and 177 deletions
89
src/clients/compositor/mod.rs
Normal file
89
src/clients/compositor/mod.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use color_eyre::{Help, Report, Result};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use tokio::sync::broadcast;
|
||||
use tracing::debug;
|
||||
|
||||
pub mod hyprland;
|
||||
pub mod sway;
|
||||
|
||||
pub enum Compositor {
|
||||
Sway,
|
||||
Hyprland,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
impl Display for Compositor {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Compositor::Sway => "Sway",
|
||||
Compositor::Hyprland => "Hyprland",
|
||||
Compositor::Unsupported => "Unsupported",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Compositor {
|
||||
/// Attempts to get the current compositor.
|
||||
/// This is done by checking system env vars.
|
||||
fn get_current() -> Self {
|
||||
if std::env::var("SWAYSOCK").is_ok() {
|
||||
Self::Sway
|
||||
} else if std::env::var("HYPRLAND_INSTANCE_SIGNATURE").is_ok() {
|
||||
Self::Hyprland
|
||||
} else {
|
||||
Self::Unsupported
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the workspace client for the current compositor
|
||||
pub fn get_workspace_client() -> Result<&'static (dyn WorkspaceClient + Send)> {
|
||||
let current = Self::get_current();
|
||||
debug!("Getting workspace client for: {current}");
|
||||
match current {
|
||||
Compositor::Sway => Ok(sway::get_sub_client()),
|
||||
Compositor::Hyprland => Ok(hyprland::get_client()),
|
||||
Compositor::Unsupported => Err(Report::msg("Unsupported compositor")
|
||||
.note("Currently workspaces are only supported by Sway and Hyprland")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Workspace {
|
||||
/// Unique identifier
|
||||
pub id: String,
|
||||
/// Workspace friendly name
|
||||
pub name: String,
|
||||
/// Name of the monitor (output) the workspace is located on
|
||||
pub monitor: String,
|
||||
/// Whether the workspace is in focus
|
||||
pub focused: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WorkspaceUpdate {
|
||||
/// Provides an initial list of workspaces.
|
||||
/// This is re-sent to all subscribers when a new subscription is created.
|
||||
Init(Vec<Workspace>),
|
||||
Add(Workspace),
|
||||
Remove(Workspace),
|
||||
Update(Workspace),
|
||||
Move(Workspace),
|
||||
/// Declares focus moved from the old workspace to the new.
|
||||
Focus {
|
||||
old: Workspace,
|
||||
new: Workspace,
|
||||
},
|
||||
}
|
||||
|
||||
pub trait WorkspaceClient {
|
||||
/// Requests the workspace with this name is focused.
|
||||
fn focus(&self, name: String) -> Result<()>;
|
||||
|
||||
/// Creates a new to workspace event receiver.
|
||||
fn subscribe_workspace_change(&self) -> broadcast::Receiver<WorkspaceUpdate>;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue