aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-08-27 11:01:59 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-08-27 11:02:04 +0300
commit178469301b846eb9e569a029819dd03387e26379 (patch)
treebcacf43369ee061fa3242a4d6eeb383de1c8e70d
parentc637d4ce9978d2ceb9aa678c37dd69374d479bd6 (diff)
downloadniri-178469301b846eb9e569a029819dd03387e26379.tar.gz
niri-178469301b846eb9e569a029819dd03387e26379.tar.bz2
niri-178469301b846eb9e569a029819dd03387e26379.zip
config: Extract misc
-rw-r--r--niri-config/src/lib.rs168
-rw-r--r--niri-config/src/misc.rs169
2 files changed, 171 insertions, 166 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index dfc9ab2d..0888df61 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -6,7 +6,6 @@ use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
-use knuffel::errors::DecodeError;
use miette::{Context, IntoDiagnostic};
pub mod animations;
@@ -17,6 +16,7 @@ pub mod gestures;
pub mod input;
pub mod layer_rule;
pub mod layout;
+pub mod misc;
pub mod output;
pub mod utils;
pub mod window_rule;
@@ -31,6 +31,7 @@ pub use crate::gestures::Gestures;
pub use crate::input::{Input, ModKey, ScrollMethod, TrackLayout, WarpMouseToFocusMode, Xkb};
pub use crate::layer_rule::LayerRule;
pub use crate::layout::*;
+pub use crate::misc::*;
pub use crate::output::{Output, OutputName, Outputs, Position, Vrr};
pub use crate::utils::FloatOrInt;
pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule};
@@ -89,120 +90,6 @@ pub struct Config {
pub workspaces: Vec<Workspace>,
}
-#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
-pub struct SpawnAtStartup {
- #[knuffel(arguments)]
- pub command: Vec<String>,
-}
-
-#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
-pub struct SpawnShAtStartup {
- #[knuffel(argument)]
- pub command: String,
-}
-
-#[derive(knuffel::Decode, Debug, PartialEq)]
-pub struct Cursor {
- #[knuffel(child, unwrap(argument), default = String::from("default"))]
- pub xcursor_theme: String,
- #[knuffel(child, unwrap(argument), default = 24)]
- pub xcursor_size: u8,
- #[knuffel(child)]
- pub hide_when_typing: bool,
- #[knuffel(child, unwrap(argument))]
- pub hide_after_inactive_ms: Option<u32>,
-}
-
-impl Default for Cursor {
- fn default() -> Self {
- Self {
- xcursor_theme: String::from("default"),
- xcursor_size: 24,
- hide_when_typing: false,
- hide_after_inactive_ms: None,
- }
- }
-}
-
-#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
-pub struct HotkeyOverlay {
- #[knuffel(child)]
- pub skip_at_startup: bool,
- #[knuffel(child)]
- pub hide_not_bound: bool,
-}
-
-#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
-pub struct ConfigNotification {
- #[knuffel(child)]
- pub disable_failed: bool,
-}
-
-#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
-pub struct Clipboard {
- #[knuffel(child)]
- pub disable_primary: bool,
-}
-
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
-pub struct Overview {
- #[knuffel(child, unwrap(argument), default = Self::default().zoom)]
- pub zoom: FloatOrInt<0, 1>,
- #[knuffel(child, default = Self::default().backdrop_color)]
- pub backdrop_color: Color,
- #[knuffel(child, default)]
- pub workspace_shadow: appearance::WorkspaceShadow,
-}
-
-impl Default for Overview {
- fn default() -> Self {
- Self {
- zoom: FloatOrInt(0.5),
- backdrop_color: appearance::DEFAULT_BACKDROP_COLOR,
- workspace_shadow: appearance::WorkspaceShadow::default(),
- }
- }
-}
-
-#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq, Eq)]
-pub struct Environment(#[knuffel(children)] pub Vec<EnvironmentVariable>);
-
-#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
-pub struct EnvironmentVariable {
- #[knuffel(node_name)]
- pub name: String,
- #[knuffel(argument)]
- pub value: Option<String>,
-}
-
-#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
-pub struct XwaylandSatellite {
- #[knuffel(child)]
- pub off: bool,
- #[knuffel(child, unwrap(argument), default = Self::default().path)]
- pub path: String,
-}
-
-impl Default for XwaylandSatellite {
- fn default() -> Self {
- Self {
- off: false,
- path: String::from("xwayland-satellite"),
- }
- }
-}
-
-#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
-pub struct Workspace {
- #[knuffel(argument)]
- pub name: WorkspaceName,
- #[knuffel(child, unwrap(argument))]
- pub open_on_output: Option<String>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct WorkspaceName(pub String);
-
#[derive(Debug, Clone)]
pub enum ConfigPath {
/// Explicitly set config path.
@@ -345,57 +232,6 @@ impl Default for Config {
}
}
-impl<S: knuffel::traits::ErrorSpan> knuffel::DecodeScalar<S> for WorkspaceName {
- fn type_check(
- type_name: &Option<knuffel::span::Spanned<knuffel::ast::TypeName, S>>,
- ctx: &mut knuffel::decode::Context<S>,
- ) {
- if let Some(type_name) = &type_name {
- ctx.emit_error(DecodeError::unexpected(
- type_name,
- "type name",
- "no type name expected for this node",
- ));
- }
- }
-
- fn raw_decode(
- val: &knuffel::span::Spanned<knuffel::ast::Literal, S>,
- ctx: &mut knuffel::decode::Context<S>,
- ) -> Result<WorkspaceName, DecodeError<S>> {
- #[derive(Debug)]
- struct WorkspaceNameSet(Vec<String>);
- match &**val {
- knuffel::ast::Literal::String(ref s) => {
- let mut name_set: Vec<String> = match ctx.get::<WorkspaceNameSet>() {
- Some(h) => h.0.clone(),
- None => Vec::new(),
- };
-
- if name_set.iter().any(|name| name.eq_ignore_ascii_case(s)) {
- ctx.emit_error(DecodeError::unexpected(
- val,
- "named workspace",
- format!("duplicate named workspace: {s}"),
- ));
- return Ok(Self(String::new()));
- }
-
- name_set.push(s.to_string());
- ctx.set(WorkspaceNameSet(name_set));
- Ok(Self(s.clone().into()))
- }
- _ => {
- ctx.emit_error(DecodeError::unsupported(
- val,
- "workspace names must be strings",
- ));
- Ok(Self(String::new()))
- }
- }
- }
-}
-
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
diff --git a/niri-config/src/misc.rs b/niri-config/src/misc.rs
new file mode 100644
index 00000000..444fe772
--- /dev/null
+++ b/niri-config/src/misc.rs
@@ -0,0 +1,169 @@
+use knuffel::errors::DecodeError;
+
+use crate::appearance::{Color, WorkspaceShadow, DEFAULT_BACKDROP_COLOR};
+use crate::FloatOrInt;
+
+#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
+pub struct SpawnAtStartup {
+ #[knuffel(arguments)]
+ pub command: Vec<String>,
+}
+
+#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
+pub struct SpawnShAtStartup {
+ #[knuffel(argument)]
+ pub command: String,
+}
+
+#[derive(knuffel::Decode, Debug, PartialEq)]
+pub struct Cursor {
+ #[knuffel(child, unwrap(argument), default = String::from("default"))]
+ pub xcursor_theme: String,
+ #[knuffel(child, unwrap(argument), default = 24)]
+ pub xcursor_size: u8,
+ #[knuffel(child)]
+ pub hide_when_typing: bool,
+ #[knuffel(child, unwrap(argument))]
+ pub hide_after_inactive_ms: Option<u32>,
+}
+
+impl Default for Cursor {
+ fn default() -> Self {
+ Self {
+ xcursor_theme: String::from("default"),
+ xcursor_size: 24,
+ hide_when_typing: false,
+ hide_after_inactive_ms: None,
+ }
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub struct HotkeyOverlay {
+ #[knuffel(child)]
+ pub skip_at_startup: bool,
+ #[knuffel(child)]
+ pub hide_not_bound: bool,
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub struct ConfigNotification {
+ #[knuffel(child)]
+ pub disable_failed: bool,
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub struct Clipboard {
+ #[knuffel(child)]
+ pub disable_primary: bool,
+}
+
+#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+pub struct Overview {
+ #[knuffel(child, unwrap(argument), default = Self::default().zoom)]
+ pub zoom: FloatOrInt<0, 1>,
+ #[knuffel(child, default = Self::default().backdrop_color)]
+ pub backdrop_color: Color,
+ #[knuffel(child, default)]
+ pub workspace_shadow: WorkspaceShadow,
+}
+
+impl Default for Overview {
+ fn default() -> Self {
+ Self {
+ zoom: FloatOrInt(0.5),
+ backdrop_color: DEFAULT_BACKDROP_COLOR,
+ workspace_shadow: WorkspaceShadow::default(),
+ }
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq, Eq)]
+pub struct Environment(#[knuffel(children)] pub Vec<EnvironmentVariable>);
+
+#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
+pub struct EnvironmentVariable {
+ #[knuffel(node_name)]
+ pub name: String,
+ #[knuffel(argument)]
+ pub value: Option<String>,
+}
+
+#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
+pub struct XwaylandSatellite {
+ #[knuffel(child)]
+ pub off: bool,
+ #[knuffel(child, unwrap(argument), default = Self::default().path)]
+ pub path: String,
+}
+
+impl Default for XwaylandSatellite {
+ fn default() -> Self {
+ Self {
+ off: false,
+ path: String::from("xwayland-satellite"),
+ }
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
+pub struct Workspace {
+ #[knuffel(argument)]
+ pub name: WorkspaceName,
+ #[knuffel(child, unwrap(argument))]
+ pub open_on_output: Option<String>,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct WorkspaceName(pub String);
+
+impl<S: knuffel::traits::ErrorSpan> knuffel::DecodeScalar<S> for WorkspaceName {
+ fn type_check(
+ type_name: &Option<knuffel::span::Spanned<knuffel::ast::TypeName, S>>,
+ ctx: &mut knuffel::decode::Context<S>,
+ ) {
+ if let Some(type_name) = &type_name {
+ ctx.emit_error(DecodeError::unexpected(
+ type_name,
+ "type name",
+ "no type name expected for this node",
+ ));
+ }
+ }
+
+ fn raw_decode(
+ val: &knuffel::span::Spanned<knuffel::ast::Literal, S>,
+ ctx: &mut knuffel::decode::Context<S>,
+ ) -> Result<WorkspaceName, DecodeError<S>> {
+ #[derive(Debug)]
+ struct WorkspaceNameSet(Vec<String>);
+ match &**val {
+ knuffel::ast::Literal::String(ref s) => {
+ let mut name_set: Vec<String> = match ctx.get::<WorkspaceNameSet>() {
+ Some(h) => h.0.clone(),
+ None => Vec::new(),
+ };
+
+ if name_set.iter().any(|name| name.eq_ignore_ascii_case(s)) {
+ ctx.emit_error(DecodeError::unexpected(
+ val,
+ "named workspace",
+ format!("duplicate named workspace: {s}"),
+ ));
+ return Ok(Self(String::new()));
+ }
+
+ name_set.push(s.to_string());
+ ctx.set(WorkspaceNameSet(name_set));
+ Ok(Self(s.clone().into()))
+ }
+ _ => {
+ ctx.emit_error(DecodeError::unsupported(
+ val,
+ "workspace names must be strings",
+ ));
+ Ok(Self(String::new()))
+ }
+ }
+ }
+}