From d5f4e79e4c35d4f5a7a4a64e85e72fb1545ef2db Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 20 Sep 2025 09:37:52 +0300 Subject: Add per-workspace layout config Per-workspace background-color doesn't work yet. --- niri-config/src/lib.rs | 5 ++++- niri-config/src/workspace.rs | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'niri-config/src') diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 6dd32620..e969b250 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -38,7 +38,7 @@ pub use crate::output::{Output, OutputName, Outputs, Position, Vrr}; pub use crate::utils::FloatOrInt; use crate::utils::MergeWith as _; pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule}; -pub use crate::workspace::Workspace; +pub use crate::workspace::{Workspace, WorkspaceLayoutPart}; #[derive(knuffel::Decode, Debug, PartialEq)] pub struct Config { @@ -1795,18 +1795,21 @@ mod tests { open_on_output: Some( "eDP-1", ), + layout: None, }, Workspace { name: WorkspaceName( "workspace-2", ), open_on_output: None, + layout: None, }, Workspace { name: WorkspaceName( "workspace-3", ), open_on_output: None, + layout: None, }, ], } diff --git a/niri-config/src/workspace.rs b/niri-config/src/workspace.rs index e502bdb7..d34dcf46 100644 --- a/niri-config/src/workspace.rs +++ b/niri-config/src/workspace.rs @@ -1,16 +1,50 @@ use knuffel::errors::DecodeError; -#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] +use crate::LayoutPart; + +#[derive(knuffel::Decode, Debug, Clone, PartialEq)] pub struct Workspace { #[knuffel(argument)] pub name: WorkspaceName, #[knuffel(child, unwrap(argument))] pub open_on_output: Option, + #[knuffel(child)] + pub layout: Option, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct WorkspaceName(pub String); +#[derive(Debug, Clone, PartialEq)] +pub struct WorkspaceLayoutPart(pub LayoutPart); + +impl knuffel::Decode for WorkspaceLayoutPart { + fn decode_node( + node: &knuffel::ast::SpannedNode, + ctx: &mut knuffel::decode::Context, + ) -> Result> { + for child in node.children() { + let name = &**child.node_name; + + // Check for disallowed properties. + // + // - empty-workspace-above-first is a monitor-level concept. + // - insert-hint customization could make sense for workspaces, however currently it is + // also handled at the monitor level (since insert hints in-between workspaces are a + // monitor-level concept), so for now this config option would do nothing. + if matches!(name, "empty-workspace-above-first" | "insert-hint") { + ctx.emit_error(DecodeError::unexpected( + child, + "node", + format!("node `{name}` is not allowed inside `workspace.layout`"), + )); + } + } + + LayoutPart::decode_node(node, ctx).map(Self) + } +} + impl knuffel::DecodeScalar for WorkspaceName { fn type_check( type_name: &Option>, -- cgit