From a4adf56b49f9718529ddfee31009f22e844e5979 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 7 Jan 2024 08:02:40 +0400 Subject: [PATCH] [WIP, incomplete] Port config to TOML --- Cargo.lock | 316 ++++++++++++++++--------- Cargo.toml | 4 +- src/backend/tty.rs | 5 +- src/backend/winit.rs | 5 +- src/config.rs | 551 +++++++++++++++++++------------------------ src/input.rs | 26 +- src/layout/mod.rs | 3 +- src/main.rs | 5 +- src/niri.rs | 5 +- 9 files changed, 469 insertions(+), 451 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f60df23c..771dbac6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,12 +30,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "android-activity" version = "0.5.1" @@ -63,6 +57,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.5" @@ -552,12 +561,16 @@ dependencies = [ ] [[package]] -name = "chumsky" -version = "0.9.3" +name = "chrono" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ - "hashbrown", + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.48.5", ] [[package]] @@ -734,6 +747,41 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + [[package]] name = "deranged" version = "0.3.11" @@ -741,6 +789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1196,24 +1245,23 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] [[package]] name = "hermit-abi" @@ -1227,6 +1275,29 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icrate" version = "0.0.4" @@ -1238,6 +1309,12 @@ dependencies = [ "objc2", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -1248,6 +1325,17 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -1255,7 +1343,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", + "serde", ] [[package]] @@ -1306,6 +1395,12 @@ version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + [[package]] name = "jni" version = "0.21.1" @@ -1361,33 +1456,6 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" -[[package]] -name = "knuffel" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04bee6ddc6071011314b1ce4f7705fef6c009401dba4fd22cb0009db6a177413" -dependencies = [ - "base64", - "chumsky", - "knuffel-derive", - "miette", - "thiserror", - "unicode-width", -] - -[[package]] -name = "knuffel-derive" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91977f56c49cfb961e3d840e2e7c6e4a56bde7283898cf606861f1421348283d" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1622,29 +1690,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "miette" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" -dependencies = [ - "miette-derive", - "once_cell", - "thiserror", - "unicode-width", -] - -[[package]] -name = "miette-derive" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1704,11 +1749,9 @@ dependencies = [ "directories", "git-version", "keyframe", - "knuffel", "libc", "log", "logind-zbus", - "miette", "notify-rust", "pipewire", "png", @@ -1718,8 +1761,10 @@ dependencies = [ "proptest-derive", "sd-notify", "serde", + "serde_with", "smithay", "smithay-drm-extras", + "toml", "tracing", "tracing-subscriber", "tracy-client", @@ -1799,7 +1844,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -2041,36 +2086,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "toml_edit 0.20.7", ] [[package]] @@ -2326,6 +2346,12 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + [[package]] name = "same-file" version = "1.0.6" @@ -2373,6 +2399,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.18" @@ -2393,6 +2430,35 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "sha1" version = "0.10.6" @@ -2467,7 +2533,7 @@ dependencies = [ "errno", "gbm", "gl_generator", - "indexmap", + "indexmap 2.1.0", "input", "lazy_static", "libc", @@ -2661,9 +2727,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", + "itoa", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2672,6 +2740,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2689,21 +2766,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.8.2" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -2714,18 +2791,29 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap", + "indexmap 2.1.0", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap", + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", @@ -2886,12 +2974,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "url" version = "2.5.0" @@ -3500,9 +3582,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.32" +version = "0.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" +checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 1d079ea0..9302ab91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,11 +20,9 @@ clap = { version = "4.4.13", features = ["derive"] } directories = "5.0.1" git-version = "0.3.9" keyframe = { version = "1.1.1", default-features = false } -knuffel = "3.2.0" libc = "0.2.151" logind-zbus = { version = "3.1.2", optional = true } log = { version = "0.4.20", features = ["max_level_trace", "release_max_level_debug"] } -miette = "5.10.0" notify-rust = { version = "4.10.0", optional = true } pipewire = { version = "0.7.2", optional = true } png = "0.17.10" @@ -32,6 +30,8 @@ portable-atomic = { version = "1.6.0", default-features = false, features = ["fl profiling = "1.0.13" sd-notify = "0.4.1" serde = { version = "1.0.195", features = ["derive"] } +serde_with = "3.4.0" +toml = { version = "0.8.8", default-features = false, features = ["parse"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing = { version = "0.1.40", features = ["max_level_trace", "release_max_level_debug"] } tracy-client = { version = "0.16.5", default-features = false } diff --git a/src/backend/tty.rs b/src/backend/tty.rs index ab7a7e84..15c1036f 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -595,9 +595,8 @@ impl Tty { let config = self .config .borrow() - .outputs - .iter() - .find(|o| o.name == output_name) + .output + .get(&output_name) .cloned() .unwrap_or_default(); diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 492215b5..a6acc8fa 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -41,9 +41,8 @@ impl Winit { let output_config = config .borrow() - .outputs - .iter() - .find(|o| o.name == "winit") + .output + .get("winit") .cloned() .unwrap_or_default(); diff --git a/src/config.rs b/src/config.rs index 123712e9..4e29d271 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,86 +1,104 @@ +use std::collections::HashMap; use std::path::PathBuf; use std::str::FromStr; +use anyhow::{bail, Context}; use bitflags::bitflags; use directories::ProjectDirs; -use miette::{miette, Context, IntoDiagnostic}; +use serde::Deserialize; +use serde_with::DeserializeFromStr; use smithay::input::keyboard::keysyms::KEY_NoSymbol; use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE}; use smithay::input::keyboard::{Keysym, XkbConfig}; -#[derive(knuffel::Decode, Debug, PartialEq)] +#[derive(Deserialize, Debug, PartialEq)] +#[serde(deny_unknown_fields)] pub struct Config { - #[knuffel(child, default)] + #[serde(default)] pub input: Input, - #[knuffel(children(name = "output"))] - pub outputs: Vec, - #[knuffel(child, default)] + #[serde(default)] + pub output: HashMap, + #[serde(default)] pub layout: Layout, - #[knuffel(child, default)] + #[serde(default)] pub clients: Clients, - #[knuffel(child, default)] + #[serde(default)] pub cursor: Cursor, - #[knuffel(child, default)] + #[serde(default)] pub screenshot_ui: ScreenshotUi, - #[knuffel(child, default)] - pub binds: Binds, - #[knuffel(child, default)] + // Running niri without binds doesn't make much sense. + pub binds: HashMap, + #[serde(default)] pub debug: DebugConfig, } // FIXME: Add other devices. -#[derive(knuffel::Decode, Debug, Default, PartialEq)] +#[derive(Deserialize, Debug, Default, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct Input { - #[knuffel(child, default)] pub keyboard: Keyboard, - #[knuffel(child, default)] pub touchpad: Touchpad, - #[knuffel(child, default)] pub tablet: Tablet, - #[knuffel(child)] pub disable_power_key_handling: bool, } -#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)] +#[derive(Deserialize, Debug, PartialEq, Eq)] +#[serde(deny_unknown_fields, default)] pub struct Keyboard { - #[knuffel(child, default)] pub xkb: Xkb, - // The defaults were chosen to match wlroots and sway. - #[knuffel(child, unwrap(argument), default = 600)] pub repeat_delay: u16, - #[knuffel(child, unwrap(argument), default = 25)] pub repeat_rate: u8, - #[knuffel(child, unwrap(argument), default)] pub track_layout: TrackLayout, } -#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq, Clone)] +impl Default for Keyboard { + fn default() -> Self { + Self { + xkb: Default::default(), + // The defaults were chosen to match wlroots and sway. + repeat_delay: 600, + repeat_rate: 25, + track_layout: Default::default(), + } + } +} + +#[derive(Deserialize, Debug, PartialEq, Eq, Clone)] +#[serde(deny_unknown_fields, default)] pub struct Xkb { - #[knuffel(child, unwrap(argument), default)] pub rules: String, - #[knuffel(child, unwrap(argument), default)] pub model: String, - #[knuffel(child, unwrap(argument))] - pub layout: Option, - #[knuffel(child, unwrap(argument), default)] + pub layout: String, pub variant: String, - #[knuffel(child, unwrap(argument))] pub options: Option, } +impl Default for Xkb { + fn default() -> Self { + Self { + rules: String::new(), + model: String::new(), + layout: String::from("us"), + variant: String::new(), + options: None, + } + } +} + impl Xkb { pub fn to_xkb_config(&self) -> XkbConfig { XkbConfig { rules: &self.rules, model: &self.model, - layout: self.layout.as_deref().unwrap_or("us"), + layout: &self.layout, variant: &self.variant, options: self.options.clone(), } } } -#[derive(knuffel::DecodeScalar, Debug, Default, PartialEq, Eq)] +#[derive(Deserialize, Debug, Default, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] pub enum TrackLayout { /// The layout change is global. #[default] @@ -90,33 +108,26 @@ pub enum TrackLayout { } // FIXME: Add the rest of the settings. -#[derive(knuffel::Decode, Debug, Default, PartialEq)] +#[derive(Deserialize, Debug, Default, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct Touchpad { - #[knuffel(child)] pub tap: bool, - #[knuffel(child)] pub natural_scroll: bool, - #[knuffel(child, unwrap(argument), default)] pub accel_speed: f64, } -#[derive(knuffel::Decode, Debug, Default, PartialEq)] +#[derive(Deserialize, Debug, Default, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct Tablet { - #[knuffel(child, unwrap(argument))] pub map_to_output: Option, } -#[derive(knuffel::Decode, Debug, Clone, PartialEq)] +#[derive(Deserialize, Debug, Clone, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct Output { - #[knuffel(child)] pub off: bool, - #[knuffel(argument)] - pub name: String, - #[knuffel(child, unwrap(argument), default = 1.)] pub scale: f64, - #[knuffel(child)] pub position: Option, - #[knuffel(child, unwrap(argument, str))] pub mode: Option, } @@ -124,7 +135,6 @@ impl Default for Output { fn default() -> Self { Self { off: false, - name: String::new(), scale: 1., position: None, mode: None, @@ -132,52 +142,55 @@ impl Default for Output { } } -#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] +#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub struct Position { - #[knuffel(property)] pub x: i32, - #[knuffel(property)] pub y: i32, } -#[derive(Debug, Clone, PartialEq)] +#[derive(DeserializeFromStr, Debug, Clone, PartialEq)] pub struct Mode { pub width: u16, pub height: u16, pub refresh: Option, } -#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)] +#[derive(Deserialize, Debug, Clone, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct Layout { - #[knuffel(child, default)] pub focus_ring: FocusRing, - #[knuffel(child, default = default_border())] pub border: FocusRing, - #[knuffel(child, unwrap(children), default)] pub preset_column_widths: Vec, - #[knuffel(child)] - pub default_column_width: Option, - #[knuffel(child, unwrap(argument), default = 16)] + // TODO + pub default_column_width: Option, pub gaps: u16, - #[knuffel(child, default)] pub struts: Struts, } -#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] -pub struct SpawnAtStartup { - #[knuffel(arguments)] - pub command: Vec, +impl Default for Layout { + fn default() -> Self { + Self { + focus_ring: Default::default(), + border: default_border(), + preset_column_widths: vec![ + PresetWidth::Proportion(0.333), + PresetWidth::Proportion(0.5), + PresetWidth::Proportion(0.667), + ], + default_column_width: Some(PresetWidth::Proportion(0.5)), + gaps: 16, + struts: Default::default(), + } + } } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(Deserialize, Debug, Clone, Copy, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct FocusRing { - #[knuffel(child)] pub off: bool, - #[knuffel(child, unwrap(argument), default = 4)] pub width: u16, - #[knuffel(child, default = Color::new(127, 200, 255, 255))] pub active_color: Color, - #[knuffel(child, default = Color::new(80, 80, 80, 255))] pub inactive_color: Color, } @@ -201,15 +214,12 @@ pub const fn default_border() -> FocusRing { } } -#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)] +#[serde(from = "[u8; 4]")] pub struct Color { - #[knuffel(argument)] pub r: u8, - #[knuffel(argument)] pub g: u8, - #[knuffel(argument)] pub b: u8, - #[knuffel(argument)] pub a: u8, } @@ -225,19 +235,30 @@ impl From for [f32; 4] { } } -#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)] +impl From<[u8; 4]> for Color { + fn from(value: [u8; 4]) -> Self { + let [r, g, b, a] = value; + Self { r, g, b, a } + } +} + +#[derive(Deserialize, Debug, Default, PartialEq, Eq)] +#[serde(deny_unknown_fields, default)] pub struct Clients { - #[knuffel(child, default)] pub prefer_no_csd: bool, - #[knuffel(children(name = "spawn-at-startup"))] pub spawn_at_startup: Vec, } -#[derive(knuffel::Decode, Debug, PartialEq)] +#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct SpawnAtStartup { + pub command: Vec, +} + +#[derive(Deserialize, Debug, PartialEq)] +#[serde(deny_unknown_fields, default)] 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, } @@ -250,38 +271,26 @@ impl Default for Cursor { } } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(Deserialize, Debug, Clone, Copy, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum PresetWidth { - Proportion(#[knuffel(argument)] f64), - Fixed(#[knuffel(argument)] i32), + Proportion(f64), + Fixed(i32), } -#[derive(knuffel::Decode, Debug, Clone, PartialEq)] -pub struct DefaultColumnWidth(#[knuffel(children)] pub Vec); - -#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[serde(deny_unknown_fields, default)] pub struct Struts { - #[knuffel(child, unwrap(argument), default)] pub left: u16, - #[knuffel(child, unwrap(argument), default)] pub right: u16, - #[knuffel(child, unwrap(argument), default)] pub top: u16, - #[knuffel(child, unwrap(argument), default)] pub bottom: u16, } -#[derive(knuffel::Decode, Debug, PartialEq, Eq)] +#[derive(Deserialize, Debug, PartialEq, Eq)] +#[serde(deny_unknown_fields, default)] pub struct ScreenshotUi { - #[knuffel(child)] pub disable_saving_to_disk: bool, - #[knuffel( - child, - unwrap(argument), - default = String::from( - "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" - )) - ] pub screenshot_path: String, } @@ -296,25 +305,14 @@ impl Default for ScreenshotUi { } } -#[derive(knuffel::Decode, Debug, Default, PartialEq)] -pub struct Binds(#[knuffel(children)] pub Vec); - -#[derive(knuffel::Decode, Debug, PartialEq)] -pub struct Bind { - #[knuffel(node_name)] - pub key: Key, - #[knuffel(children)] - pub actions: Vec, -} - -#[derive(Debug, PartialEq, Eq)] +#[derive(DeserializeFromStr, Debug, PartialEq, Eq, Hash)] pub struct Key { pub keysym: Keysym, pub modifiers: Modifiers, } bitflags! { - #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Modifiers : u8 { const CTRL = 1; const SHIFT = 2; @@ -324,18 +322,19 @@ bitflags! { } } -#[derive(knuffel::Decode, Debug, Clone, PartialEq)] +#[derive(Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum Action { Quit, - #[knuffel(skip)] + #[serde(skip)] ChangeVt(i32), Suspend, PowerOffMonitors, ToggleDebugTint, - Spawn(#[knuffel(arguments)] Vec), - #[knuffel(skip)] + Spawn(Vec), + #[serde(skip)] ConfirmScreenshot, - #[knuffel(skip)] + #[serde(skip)] CancelScreenshot, Screenshot, ScreenshotScreen, @@ -363,10 +362,10 @@ pub enum Action { CenterColumn, FocusWorkspaceDown, FocusWorkspaceUp, - FocusWorkspace(#[knuffel(argument)] u8), + FocusWorkspace(u8), MoveWindowToWorkspaceDown, MoveWindowToWorkspaceUp, - MoveWindowToWorkspace(#[knuffel(argument)] u8), + MoveWindowToWorkspace(u8), MoveWorkspaceDown, MoveWorkspaceUp, FocusMonitorLeft, @@ -377,14 +376,14 @@ pub enum Action { MoveWindowToMonitorRight, MoveWindowToMonitorDown, MoveWindowToMonitorUp, - SetWindowHeight(#[knuffel(argument, str)] SizeChange), + SetWindowHeight(SizeChange), SwitchPresetColumnWidth, MaximizeColumn, - SetColumnWidth(#[knuffel(argument, str)] SizeChange), - SwitchLayout(#[knuffel(argument)] LayoutAction), + SetColumnWidth(SizeChange), + SwitchLayout(LayoutAction), } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(DeserializeFromStr, Debug, Clone, Copy, PartialEq)] pub enum SizeChange { SetFixed(i32), SetProportion(f64), @@ -392,27 +391,22 @@ pub enum SizeChange { AdjustProportion(f64), } -#[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq)] +#[derive(Deserialize, Debug, Clone, Copy, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum LayoutAction { Next, Prev, } -#[derive(knuffel::Decode, Debug, PartialEq)] +#[derive(Deserialize, Debug, PartialEq)] +#[serde(deny_unknown_fields, default)] pub struct DebugConfig { - #[knuffel(child, unwrap(argument), default = 1.)] pub animation_slowdown: f64, - #[knuffel(child)] pub dbus_interfaces_in_non_session_instances: bool, - #[knuffel(child)] pub wait_for_frame_completion_before_queueing: bool, - #[knuffel(child)] pub enable_color_transformations_capability: bool, - #[knuffel(child)] pub enable_overlay_planes: bool, - #[knuffel(child)] pub disable_cursor_plane: bool, - #[knuffel(child, unwrap(argument))] pub render_drm_device: Option, } @@ -431,67 +425,55 @@ impl Default for DebugConfig { } impl Config { - pub fn load(path: Option) -> miette::Result<(Self, PathBuf)> { + pub fn load(path: Option) -> anyhow::Result<(Self, PathBuf)> { let path = if let Some(path) = path { path } else { let mut path = ProjectDirs::from("", "", "niri") - .ok_or_else(|| miette!("error retrieving home directory"))? + .context("error retrieving home directory")? .config_dir() .to_owned(); path.push("config.kdl"); path }; - let contents = std::fs::read_to_string(&path) - .into_diagnostic() - .with_context(|| format!("error reading {path:?}"))?; + let contents = + std::fs::read_to_string(&path).with_context(|| format!("error reading {path:?}"))?; - let config = Self::parse("config.kdl", &contents).context("error parsing")?; + let config = Self::parse(&contents).context("error parsing")?; debug!("loaded config from {path:?}"); Ok((config, path)) } - pub fn parse(filename: &str, text: &str) -> Result { - knuffel::parse(filename, text) + pub fn parse(text: &str) -> Result { + toml::from_str(text) } } impl Default for Config { fn default() -> Self { - Config::parse( - "default-config.kdl", - include_str!("../resources/default-config.kdl"), - ) - .unwrap() + Config::parse(include_str!("../resources/default-config.kdl")) + .context("error parsing default config") + .unwrap() } } impl FromStr for Mode { - type Err = miette::Error; + type Err = anyhow::Error; fn from_str(s: &str) -> Result { - let Some((width, rest)) = s.split_once('x') else { - return Err(miette!("no 'x' separator found")); - }; + let (width, rest) = s.split_once('x').context("no 'x' separator found")?; let (height, refresh) = match rest.split_once('@') { Some((height, refresh)) => (height, Some(refresh)), None => (rest, None), }; - let width = width - .parse() - .into_diagnostic() - .context("error parsing width")?; - let height = height - .parse() - .into_diagnostic() - .context("error parsing height")?; + let width = width.parse().context("error parsing width")?; + let height = height.parse().context("error parsing height")?; let refresh = refresh .map(str::parse) .transpose() - .into_diagnostic() .context("error parsing refresh rate")?; Ok(Self { @@ -503,7 +485,7 @@ impl FromStr for Mode { } impl FromStr for Key { - type Err = miette::Error; + type Err = anyhow::Error; fn from_str(s: &str) -> Result { let mut modifiers = Modifiers::empty(); @@ -524,13 +506,13 @@ impl FromStr for Key { } else if part.eq_ignore_ascii_case("super") || part.eq_ignore_ascii_case("win") { modifiers |= Modifiers::SUPER; } else { - return Err(miette!("invalid modifier: {part}")); + bail!("invalid modifier: {part}"); } } let keysym = keysym_from_name(key, KEYSYM_CASE_INSENSITIVE); if keysym.raw() == KEY_NoSymbol { - return Err(miette!("invalid key: {key}")); + bail!("invalid key: {key}"); } Ok(Key { keysym, modifiers }) @@ -538,51 +520,39 @@ impl FromStr for Key { } impl FromStr for SizeChange { - type Err = miette::Error; + type Err = anyhow::Error; fn from_str(s: &str) -> Result { match s.split_once('%') { Some((value, empty)) => { if !empty.is_empty() { - return Err(miette!("trailing characters after '%' are not allowed")); + bail!("trailing characters after '%' are not allowed"); } match value.bytes().next() { Some(b'-' | b'+') => { - let value = value - .parse() - .into_diagnostic() - .context("error parsing value")?; + let value = value.parse().context("error parsing value")?; Ok(Self::AdjustProportion(value)) } Some(_) => { - let value = value - .parse() - .into_diagnostic() - .context("error parsing value")?; + let value = value.parse().context("error parsing value")?; Ok(Self::SetProportion(value)) } - None => Err(miette!("value is missing")), + None => bail!("value is missing"), } } None => { let value = s; match value.bytes().next() { Some(b'-' | b'+') => { - let value = value - .parse() - .into_diagnostic() - .context("error parsing value")?; + let value = value.parse().context("error parsing value")?; Ok(Self::AdjustFixed(value)) } Some(_) => { - let value = value - .parse() - .into_diagnostic() - .context("error parsing value")?; + let value = value.parse().context("error parsing value")?; Ok(Self::SetFixed(value)) } - None => Err(miette!("value is missing")), + None => bail!("value is missing"), } } } @@ -591,17 +561,11 @@ impl FromStr for SizeChange { #[cfg(test)] mod tests { - use miette::NarratableReportHandler; - use super::*; #[track_caller] fn check(text: &str, expected: Config) { - let _ = miette::set_hook(Box::new(|_| Box::new(NarratableReportHandler::new()))); - - let parsed = Config::parse("test.kdl", text) - .map_err(miette::Report::new) - .unwrap(); + let parsed = Config::parse(text).map_err(anyhow::Error::new).unwrap(); assert_eq!(parsed, expected); } @@ -609,101 +573,80 @@ mod tests { fn parse() { check( r#" - input { - keyboard { - repeat-delay 600 - repeat-rate 25 - track-layout "window" - xkb { - layout "us,ru" - options "grp:win_space_toggle" - } - } + [input] + disable_power_key_handling = true - touchpad { - tap - accel-speed 0.2 - } + [input.keyboard] + repeat_delay = 600 + repeat_rate = 25 + track_layout = 'window' + xkb.layout = 'us,ru' + xkb.options = 'grp:win_space_toggle' - tablet { - map-to-output "eDP-1" - } + [input.touchpad] + tap = true + accel_speed = 0.2 - disable-power-key-handling - } + [input.tablet] + map_to_output = 'eDP-1' - output "eDP-1" { - scale 2.0 - position x=10 y=20 - mode "1920x1080@144" - } + [output.'eDP-1'] + scale = 2.0 + position = { x = 10, y = 20 } + mode = '1920x1080@144' - layout { - focus-ring { - width 5 - active-color 0 100 200 255 - inactive-color 255 200 100 0 - } + [layout] + gaps = 8 + preset_column_widths = [ + { proportion = 0.25 }, + { proportion = 0.5 }, + { fixed = 960 }, + { fixed = 1280 }, + ] + default_column_width = { proportion = 0.25 } + struts = { left = 1, right = 2, top = 3 } - border { - width 3 - active-color 0 100 200 255 - inactive-color 255 200 100 0 - } + [layout.focus_ring] + width = 5 + active_color = [0, 100, 200, 255] + inactive_color = [255, 200, 100, 0] - preset-column-widths { - proportion 0.25 - proportion 0.5 - fixed 960 - fixed 1280 - } + [layout.border] + width = 3 + active_color = [0, 100, 200, 255] + inactive_color = [255, 200, 100, 0] - default-column-width { proportion 0.25; } + [clients] + prefer_no_csd = true + spawn_at_startup = [ + { command = ['alacritty', '-e', 'fish'] }, + ] - gaps 8 + [cursor] + xcursor_theme = 'breeze_cursors' + xcursor_size = 16 - struts { - left 1 - right 2 - top 3 - } - } + [screenshot_ui] + screenshot_path = '~/Screenshots/screenshot.png' + disable_saving_to_disk = true - clients { - prefer-no-csd + [binds] + 'Mod+T' = { spawn = ['alacritty'] } + 'Mod+Q' = 'close_window' + 'Mod+Shift+H' = 'focus_monitor_left' + 'Mod+Ctrl+Shift+L' = 'move_window_to_monitor_right' + 'Mod+Comma' = 'consume_window_into_column' + 'Mod+1' = { focus_workspace = 1 } - spawn-at-startup "alacritty" "-e" "fish" - } - - cursor { - xcursor-theme "breeze_cursors" - xcursor-size 16 - } - - screenshot-ui { - screenshot-path "~/Screenshots/screenshot.png" - disable-saving-to-disk - } - - binds { - Mod+T { spawn "alacritty"; } - Mod+Q { close-window; } - Mod+Shift+H { focus-monitor-left; } - Mod+Ctrl+Shift+L { move-window-to-monitor-right; } - Mod+Comma { consume-window-into-column; } - Mod+1 { focus-workspace 1;} - } - - debug { - animation-slowdown 2.0 - render-drm-device "/dev/dri/renderD129" - } + [debug] + animation_slowdown = 2.0 + render_drm_device = '/dev/dri/renderD129' "#, Config { input: Input { keyboard: Keyboard { xkb: Xkb { - layout: Some("us,ru".to_owned()), + layout: "us,ru".to_owned(), options: Some("grp:win_space_toggle".to_owned()), ..Default::default() }, @@ -721,17 +664,19 @@ mod tests { }, disable_power_key_handling: true, }, - outputs: vec![Output { - off: false, - name: "eDP-1".to_owned(), - scale: 2., - position: Some(Position { x: 10, y: 20 }), - mode: Some(Mode { - width: 1920, - height: 1080, - refresh: Some(144.), - }), - }], + output: HashMap::from([( + "eDP-1".to_owned(), + Output { + off: false, + scale: 2., + position: Some(Position { x: 10, y: 20 }), + mode: Some(Mode { + width: 1920, + height: 1080, + refresh: Some(144.), + }), + }, + )]), layout: Layout { focus_ring: FocusRing { off: false, @@ -771,9 +716,7 @@ mod tests { PresetWidth::Fixed(960), PresetWidth::Fixed(1280), ], - default_column_width: Some(DefaultColumnWidth(vec![PresetWidth::Proportion( - 0.25, - )])), + default_column_width: Some(PresetWidth::Proportion(0.25)), gaps: 8, struts: Struts { left: 1, @@ -796,49 +739,49 @@ mod tests { disable_saving_to_disk: true, screenshot_path: String::from("~/Screenshots/screenshot.png"), }, - binds: Binds(vec![ - Bind { - key: Key { + binds: HashMap::from([ + ( + Key { keysym: Keysym::t, modifiers: Modifiers::COMPOSITOR, }, - actions: vec![Action::Spawn(vec!["alacritty".to_owned()])], - }, - Bind { - key: Key { + Action::Spawn(vec!["alacritty".to_owned()]), + ), + ( + Key { keysym: Keysym::q, modifiers: Modifiers::COMPOSITOR, }, - actions: vec![Action::CloseWindow], - }, - Bind { - key: Key { + Action::CloseWindow, + ), + ( + Key { keysym: Keysym::h, modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT, }, - actions: vec![Action::FocusMonitorLeft], - }, - Bind { - key: Key { + Action::FocusMonitorLeft, + ), + ( + Key { keysym: Keysym::l, modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL, }, - actions: vec![Action::MoveWindowToMonitorRight], - }, - Bind { - key: Key { + Action::MoveWindowToMonitorRight, + ), + ( + Key { keysym: Keysym::comma, modifiers: Modifiers::COMPOSITOR, }, - actions: vec![Action::ConsumeWindowIntoColumn], - }, - Bind { - key: Key { + Action::ConsumeWindowIntoColumn, + ), + ( + Key { keysym: Keysym::_1, modifiers: Modifiers::COMPOSITOR, }, - actions: vec![Action::FocusWorkspace(1)], - }, + Action::FocusWorkspace(1), + ), ]), debug: DebugConfig { animation_slowdown: 2., diff --git a/src/input.rs b/src/input.rs index 4865e7e0..f56dc059 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,5 +1,5 @@ use std::any::Any; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use smithay::backend::input::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, @@ -20,7 +20,7 @@ use smithay::utils::{Logical, Point, SERIAL_COUNTER}; use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraint}; use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait}; -use crate::config::{Action, Binds, LayoutAction, Modifiers}; +use crate::config::{Action, Key, LayoutAction, Modifiers}; use crate::niri::State; use crate::screenshot_ui::ScreenshotUi; use crate::utils::{center, get_monotonic_time, spawn}; @@ -1179,7 +1179,7 @@ impl State { #[allow(clippy::too_many_arguments)] fn should_intercept_key( suppressed_keys: &mut HashSet, - bindings: &Binds, + bindings: &HashMap, comp_mod: CompositorMod, key_code: u32, modified: Keysym, @@ -1235,7 +1235,7 @@ fn should_intercept_key( } fn action( - bindings: &Binds, + bindings: &HashMap, comp_mod: CompositorMod, modified: Keysym, raw: Option, @@ -1284,13 +1284,13 @@ fn action( return None; }; - for bind in &bindings.0 { - if bind.key.keysym != raw { + for (key, action) in bindings { + if key.keysym != raw { continue; } - if bind.key.modifiers | comp_mod == modifiers { - return bind.actions.first().cloned(); + if key.modifiers | comp_mod == modifiers { + return Some(action.clone()); } } @@ -1339,18 +1339,18 @@ fn allowed_during_screenshot(action: &Action) -> bool { #[cfg(test)] mod tests { use super::*; - use crate::config::{Action, Bind, Binds, Key, Modifiers}; + use crate::config::{Action, Key, Modifiers}; #[test] fn bindings_suppress_keys() { let close_keysym = Keysym::q; - let bindings = Binds(vec![Bind { - key: Key { + let bindings = HashMap::from([( + Key { keysym: close_keysym, modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL, }, - actions: vec![Action::CloseWindow], - }]); + Action::CloseWindow, + )]); let comp_mod = CompositorMod::Super; let mut suppressed_keys = HashSet::new(); diff --git a/src/layout/mod.rs b/src/layout/mod.rs index c7fce722..6bddfd8f 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -181,8 +181,7 @@ impl Options { // while present, but empty, maps to None. let default_width = layout .default_column_width - .as_ref() - .map(|w| w.0.first().copied().map(ColumnWidth::from)) + .map(|w| Some(ColumnWidth::from(w))) // TODO .unwrap_or(Some(ColumnWidth::Proportion(0.5))); Self { diff --git a/src/main.rs b/src/main.rs index e7498c87..1f2a2ee4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,12 +27,12 @@ use std::path::PathBuf; use std::process::Command; use std::{env, mem}; +use anyhow::Context; use clap::{Parser, Subcommand}; use config::Config; #[cfg(not(feature = "xdp-gnome-screencast"))] use dummy_pw_utils as pw_utils; use git_version::git_version; -use miette::{Context, NarratableReportHandler}; use niri::{Niri, State}; use portable_atomic::Ordering; use sd_notify::NotifyState; @@ -109,9 +109,6 @@ fn main() -> Result<(), Box> { let _client = tracy_client::Client::start(); - // Set a better error printer for config loading. - miette::set_hook(Box::new(|_| Box::new(NarratableReportHandler::new()))).unwrap(); - // Handle subcommands. if let Some(subcommand) = cli.subcommand { match subcommand { diff --git a/src/niri.rs b/src/niri.rs index f72b150e..69f07745 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -831,9 +831,8 @@ impl Niri { let config = self .config .borrow() - .outputs - .iter() - .find(|o| o.name == name) + .output + .get(&name) .cloned() .unwrap_or_default();