diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-08-27 10:31:14 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-08-27 10:46:46 +0300 |
| commit | 02e3f9f66ee71ce5252df3bb7b7c9743e95fdcbc (patch) | |
| tree | 788579ba0374a25e26782c80f332469b5c8724a8 /niri-config/src/layout.rs | |
| parent | 19c576cfd88fa58c8f3e8123933e8a13ba6da3fa (diff) | |
| download | niri-02e3f9f66ee71ce5252df3bb7b7c9743e95fdcbc.tar.gz niri-02e3f9f66ee71ce5252df3bb7b7c9743e95fdcbc.tar.bz2 niri-02e3f9f66ee71ce5252df3bb7b7c9743e95fdcbc.zip | |
config: Extract appearance and layout
Diffstat (limited to 'niri-config/src/layout.rs')
| -rw-r--r-- | niri-config/src/layout.rs | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/niri-config/src/layout.rs b/niri-config/src/layout.rs new file mode 100644 index 00000000..6f9c9135 --- /dev/null +++ b/niri-config/src/layout.rs @@ -0,0 +1,132 @@ +use knuffel::errors::DecodeError; +use niri_ipc::{ColumnDisplay, SizeChange}; + +use crate::appearance::{ + Border, FocusRing, InsertHint, Shadow, TabIndicator, DEFAULT_BACKGROUND_COLOR, +}; +use crate::{expect_only_children, Color, FloatOrInt}; + +#[derive(knuffel::Decode, Debug, Clone, PartialEq)] +pub struct Layout { + #[knuffel(child, default)] + pub focus_ring: FocusRing, + #[knuffel(child, default)] + pub border: Border, + #[knuffel(child, default)] + pub shadow: Shadow, + #[knuffel(child, default)] + pub tab_indicator: TabIndicator, + #[knuffel(child, default)] + pub insert_hint: InsertHint, + #[knuffel(child, unwrap(children), default)] + pub preset_column_widths: Vec<PresetSize>, + #[knuffel(child)] + pub default_column_width: Option<DefaultPresetSize>, + #[knuffel(child, unwrap(children), default)] + pub preset_window_heights: Vec<PresetSize>, + #[knuffel(child, unwrap(argument), default)] + pub center_focused_column: CenterFocusedColumn, + #[knuffel(child)] + pub always_center_single_column: bool, + #[knuffel(child)] + pub empty_workspace_above_first: bool, + #[knuffel(child, unwrap(argument, str), default = Self::default().default_column_display)] + pub default_column_display: ColumnDisplay, + #[knuffel(child, unwrap(argument), default = Self::default().gaps)] + pub gaps: FloatOrInt<0, 65535>, + #[knuffel(child, default)] + pub struts: Struts, + #[knuffel(child, default = DEFAULT_BACKGROUND_COLOR)] + pub background_color: Color, +} + +impl Default for Layout { + fn default() -> Self { + Self { + focus_ring: Default::default(), + border: Default::default(), + shadow: Default::default(), + tab_indicator: Default::default(), + insert_hint: Default::default(), + preset_column_widths: Default::default(), + default_column_width: Default::default(), + center_focused_column: Default::default(), + always_center_single_column: false, + empty_workspace_above_first: false, + default_column_display: ColumnDisplay::Normal, + gaps: FloatOrInt(16.), + struts: Default::default(), + preset_window_heights: Default::default(), + background_color: DEFAULT_BACKGROUND_COLOR, + } + } +} + +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub enum PresetSize { + Proportion(#[knuffel(argument)] f64), + Fixed(#[knuffel(argument)] i32), +} + +impl From<PresetSize> for SizeChange { + fn from(value: PresetSize) -> Self { + match value { + PresetSize::Proportion(prop) => SizeChange::SetProportion(prop * 100.), + PresetSize::Fixed(fixed) => SizeChange::SetFixed(fixed), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct DefaultPresetSize(pub Option<PresetSize>); + +#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)] +pub struct Struts { + #[knuffel(child, unwrap(argument), default)] + pub left: FloatOrInt<-65535, 65535>, + #[knuffel(child, unwrap(argument), default)] + pub right: FloatOrInt<-65535, 65535>, + #[knuffel(child, unwrap(argument), default)] + pub top: FloatOrInt<-65535, 65535>, + #[knuffel(child, unwrap(argument), default)] + pub bottom: FloatOrInt<-65535, 65535>, +} + +#[derive(knuffel::DecodeScalar, Debug, Default, PartialEq, Eq, Clone, Copy)] +pub enum CenterFocusedColumn { + /// Focusing a column will not center the column. + #[default] + Never, + /// The focused column will always be centered. + Always, + /// Focusing a column will center it if it doesn't fit on the screen together with the + /// previously focused column. + OnOverflow, +} + +impl<S> knuffel::Decode<S> for DefaultPresetSize +where + S: knuffel::traits::ErrorSpan, +{ + fn decode_node( + node: &knuffel::ast::SpannedNode<S>, + ctx: &mut knuffel::decode::Context<S>, + ) -> Result<Self, DecodeError<S>> { + expect_only_children(node, ctx); + + let mut children = node.children(); + + if let Some(child) = children.next() { + if let Some(unwanted_child) = children.next() { + ctx.emit_error(DecodeError::unexpected( + unwanted_child, + "node", + "expected no more than one child", + )); + } + PresetSize::decode_node(child, ctx).map(Some).map(Self) + } else { + Ok(Self(None)) + } + } +} |
