Add per-workspace layout config

Per-workspace background-color doesn't work yet.
This commit is contained in:
Ivan Molodetskikh
2025-09-20 09:37:52 +03:00
parent d015c7e55b
commit d5f4e79e4c
5 changed files with 233 additions and 29 deletions
+4 -1
View File
@@ -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,
},
],
}
+35 -1
View File
@@ -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<String>,
#[knuffel(child)]
pub layout: Option<WorkspaceLayoutPart>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceName(pub String);
#[derive(Debug, Clone, PartialEq)]
pub struct WorkspaceLayoutPart(pub LayoutPart);
impl<S: knuffel::traits::ErrorSpan> knuffel::Decode<S> for WorkspaceLayoutPart {
fn decode_node(
node: &knuffel::ast::SpannedNode<S>,
ctx: &mut knuffel::decode::Context<S>,
) -> Result<Self, DecodeError<S>> {
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<S: knuffel::traits::ErrorSpan> knuffel::DecodeScalar<S> for WorkspaceName {
fn type_check(
type_name: &Option<knuffel::span::Spanned<knuffel::ast::TypeName, S>>,