Compare commits

...

4 Commits

Author SHA1 Message Date
Ivan Molodetskikh a4adf56b49 [WIP, incomplete] Port config to TOML 2024-01-07 08:03:29 +04:00
Ivan Molodetskikh 0a54db6b93 [cfg-breaking] Move prefer-no-csd and spawn-at-startup to new clients scope 2024-01-07 08:03:29 +04:00
Ivan Molodetskikh 5f7d06713e [cfg-breaking] Add screenshot-ui scope, disable-saving-to-disk
This will map better to other formats like TOML.
2024-01-07 08:03:29 +04:00
Ivan Molodetskikh f0de0d77d6 [cfg-breaking] Move layout settings into their own scope 2024-01-07 08:03:29 +04:00
12 changed files with 636 additions and 562 deletions
Generated
+199 -117
View File
@@ -30,12 +30,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]] [[package]]
name = "android-activity" name = "android-activity"
version = "0.5.1" version = "0.5.1"
@@ -63,6 +57,21 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" 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]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.5" version = "0.6.5"
@@ -552,12 +561,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "chumsky" name = "chrono"
version = "0.9.3" version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [ dependencies = [
"hashbrown", "android-tzdata",
"iana-time-zone",
"num-traits",
"serde",
"windows-targets 0.48.5",
] ]
[[package]] [[package]]
@@ -734,6 +747,41 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" 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]] [[package]]
name = "deranged" name = "deranged"
version = "0.3.11" version = "0.3.11"
@@ -741,6 +789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [ dependencies = [
"powerfmt", "powerfmt",
"serde",
] ]
[[package]] [[package]]
@@ -1196,24 +1245,23 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.3" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.1" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
@@ -1227,6 +1275,29 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 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]] [[package]]
name = "icrate" name = "icrate"
version = "0.0.4" version = "0.0.4"
@@ -1238,6 +1309,12 @@ dependencies = [
"objc2", "objc2",
] ]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.5.0" version = "0.5.0"
@@ -1248,6 +1325,17 @@ dependencies = [
"unicode-normalization", "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]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.1.0" version = "2.1.0"
@@ -1255,7 +1343,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.14.3",
"serde",
] ]
[[package]] [[package]]
@@ -1306,6 +1395,12 @@ version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c"
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"
@@ -1361,33 +1456,6 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 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]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@@ -1622,29 +1690,6 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@@ -1704,11 +1749,9 @@ dependencies = [
"directories", "directories",
"git-version", "git-version",
"keyframe", "keyframe",
"knuffel",
"libc", "libc",
"log", "log",
"logind-zbus", "logind-zbus",
"miette",
"notify-rust", "notify-rust",
"pipewire", "pipewire",
"png", "png",
@@ -1718,8 +1761,10 @@ dependencies = [
"proptest-derive", "proptest-derive",
"sd-notify", "sd-notify",
"serde", "serde",
"serde_with",
"smithay", "smithay",
"smithay-drm-extras", "smithay-drm-extras",
"toml",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"tracy-client", "tracy-client",
@@ -1799,7 +1844,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e"
dependencies = [ dependencies = [
"proc-macro-crate 2.0.1", "proc-macro-crate 2.0.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.48", "syn 2.0.48",
@@ -2041,36 +2086,11 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro-crate" name = "proc-macro-crate"
version = "2.0.1" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [ dependencies = [
"toml_datetime", "toml_edit 0.20.7",
"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",
] ]
[[package]] [[package]]
@@ -2326,6 +2346,12 @@ dependencies = [
"wait-timeout", "wait-timeout",
] ]
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@@ -2373,6 +2399,17 @@ dependencies = [
"syn 2.0.48", "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]] [[package]]
name = "serde_repr" name = "serde_repr"
version = "0.1.18" version = "0.1.18"
@@ -2393,6 +2430,35 @@ dependencies = [
"serde", "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]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.6"
@@ -2467,7 +2533,7 @@ dependencies = [
"errno", "errno",
"gbm", "gbm",
"gl_generator", "gl_generator",
"indexmap", "indexmap 2.1.0",
"input", "input",
"lazy_static", "lazy_static",
"libc", "libc",
@@ -2661,9 +2727,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa",
"powerfmt", "powerfmt",
"serde", "serde",
"time-core", "time-core",
"time-macros",
] ]
[[package]] [[package]]
@@ -2672,6 +2740,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 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]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@@ -2689,21 +2766,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.2" version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit 0.20.2", "toml_edit 0.21.0",
] ]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.3" version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@@ -2714,18 +2791,29 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [ dependencies = [
"indexmap", "indexmap 2.1.0",
"toml_datetime", "toml_datetime",
"winnow", "winnow",
] ]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.20.2" version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [ 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",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@@ -2886,12 +2974,6 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.0" version = "2.5.0"
@@ -3500,9 +3582,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.5.32" version = "0.5.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
+2 -2
View File
@@ -20,11 +20,9 @@ clap = { version = "4.4.13", features = ["derive"] }
directories = "5.0.1" directories = "5.0.1"
git-version = "0.3.9" git-version = "0.3.9"
keyframe = { version = "1.1.1", default-features = false } keyframe = { version = "1.1.1", default-features = false }
knuffel = "3.2.0"
libc = "0.2.151" libc = "0.2.151"
logind-zbus = { version = "3.1.2", optional = true } logind-zbus = { version = "3.1.2", optional = true }
log = { version = "0.4.20", features = ["max_level_trace", "release_max_level_debug"] } 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 } notify-rust = { version = "4.10.0", optional = true }
pipewire = { version = "0.7.2", optional = true } pipewire = { version = "0.7.2", optional = true }
png = "0.17.10" png = "0.17.10"
@@ -32,6 +30,8 @@ portable-atomic = { version = "1.6.0", default-features = false, features = ["fl
profiling = "1.0.13" profiling = "1.0.13"
sd-notify = "0.4.1" sd-notify = "0.4.1"
serde = { version = "1.0.195", features = ["derive"] } 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-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing = { version = "0.1.40", features = ["max_level_trace", "release_max_level_debug"] } tracing = { version = "0.1.40", features = ["max_level_trace", "release_max_level_debug"] }
tracy-client = { version = "0.16.5", default-features = false } tracy-client = { version = "0.16.5", default-features = false }
+51 -44
View File
@@ -75,13 +75,9 @@ input {
position x=1280 y=0 position x=1280 y=0
} }
// Add lines like this to spawn processes at startup. layout {
// Note that running niri as a session supports xdg-desktop-autostart, // You can change how the focus ring looks.
// which may be more convenient to use. focus-ring {
// spawn-at-startup "alacritty" "-e" "fish"
// You can change how the focus ring looks.
focus-ring {
// Uncomment this line to disable the focus ring. // Uncomment this line to disable the focus ring.
// off // off
@@ -93,10 +89,10 @@ focus-ring {
// Color of the ring on inactive monitors: red, green, blue, alpha. // Color of the ring on inactive monitors: red, green, blue, alpha.
inactive-color 80 80 80 255 inactive-color 80 80 80 255
} }
// You can also add a border. It's similar to the focus ring, but always visible. // You can also add a border. It's similar to the focus ring, but always visible.
border { border {
// The settings are the same as for the focus ring. // The settings are the same as for the focus ring.
// If you enable the border, you probably want to disable the focus ring. // If you enable the border, you probably want to disable the focus ring.
off off
@@ -104,22 +100,10 @@ border {
width 4 width 4
active-color 255 200 127 255 active-color 255 200 127 255
inactive-color 80 80 80 255 inactive-color 80 80 80 255
} }
cursor { // You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between.
// Change the theme and size of the cursor as well as set the preset-column-widths {
// `XCURSOR_THEME` and `XCURSOR_SIZE` env variables.
// xcursor-theme "default"
// xcursor-size 24
}
// Uncomment this line to ask the clients to omit their client-side decorations if possible.
// If the client will specifically ask for CSD, the request will be honored.
// Additionally, clients will be informed that they are tiled, removing some rounded corners.
// prefer-no-csd
// You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between.
preset-column-widths {
// Proportion sets the width as a fraction of the output width, taking gaps into account. // Proportion sets the width as a fraction of the output width, taking gaps into account.
// For example, you can perfectly fit four windows sized "proportion 0.25" on an output. // For example, you can perfectly fit four windows sized "proportion 0.25" on an output.
// The default preset widths are 1/3, 1/2 and 2/3 of the output. // The default preset widths are 1/3, 1/2 and 2/3 of the output.
@@ -129,35 +113,58 @@ preset-column-widths {
// Fixed sets the width in logical pixels exactly. // Fixed sets the width in logical pixels exactly.
// fixed 1920 // fixed 1920
} }
// You can change the default width of the new windows. // You can change the default width of the new windows.
default-column-width { proportion 0.5; } default-column-width { proportion 0.5; }
// If you leave the brackets empty, the windows themselves will decide their initial width. // If you leave the brackets empty, the windows themselves will decide their initial width.
// default-column-width {} // default-column-width {}
// Set gaps around windows in logical pixels. // Set gaps around windows in logical pixels.
gaps 16 gaps 16
// Struts shrink the area occupied by windows, similarly to layer-shell panels. // Struts shrink the area occupied by windows, similarly to layer-shell panels.
// You can think of them as a kind of outer gaps. They are set in logical pixels. // You can think of them as a kind of outer gaps. They are set in logical pixels.
// Left and right struts will cause the next window to the side to always be visible. // Left and right struts will cause the next window to the side to always be visible.
// Top and bottom struts will simply add outer gaps in addition to the area occupied by // Top and bottom struts will simply add outer gaps in addition to the area occupied by
// layer-shell panels and regular gaps. // layer-shell panels and regular gaps.
struts { struts {
// left 64 // left 64
// right 64 // right 64
// top 64 // top 64
// bottom 64 // bottom 64
}
} }
// You can change the path where screenshots are saved. cursor {
// A ~ at the front will be expanded to the home directory. // Change the theme and size of the cursor as well as set the
// The path is formatted with strftime(3) to give you the screenshot date and time. // `XCURSOR_THEME` and `XCURSOR_SIZE` env variables.
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" // xcursor-theme "default"
// xcursor-size 24
}
// You can also set this to null to disable saving screenshots to disk. clients {
// screenshot-path null // Uncomment this line to ask the clients to omit their client-side decorations if possible.
// If the client will specifically ask for CSD, the request will be honored.
// Additionally, clients will be informed that they are tiled, removing some rounded corners.
// prefer-no-csd
// Add lines like this to spawn processes at startup.
// Note that running niri as a session supports xdg-desktop-autostart,
// which may be more convenient to use.
// spawn-at-startup "alacritty" "-e" "fish"
}
screenshot-ui {
// You can change the path where screenshots are saved.
// A ~ at the front will be expanded to the home directory.
// The path is formatted with strftime(3) to give you the screenshot date and time.
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
// Uncomment this line to disable saving screenshots to disk.
// They will only be copied to the clipboard.
// disable-saving-to-disk
}
binds { binds {
// Keys consist of modifiers separated by + signs, followed by an XKB key name // Keys consist of modifiers separated by + signs, followed by an XKB key name
+2 -3
View File
@@ -595,9 +595,8 @@ impl Tty {
let config = self let config = self
.config .config
.borrow() .borrow()
.outputs .output
.iter() .get(&output_name)
.find(|o| o.name == output_name)
.cloned() .cloned()
.unwrap_or_default(); .unwrap_or_default();
+2 -3
View File
@@ -41,9 +41,8 @@ impl Winit {
let output_config = config let output_config = config
.borrow() .borrow()
.outputs .output
.iter() .get("winit")
.find(|o| o.name == "winit")
.cloned() .cloned()
.unwrap_or_default(); .unwrap_or_default();
+284 -294
View File
@@ -1,104 +1,104 @@
use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use anyhow::{bail, Context};
use bitflags::bitflags; use bitflags::bitflags;
use directories::ProjectDirs; 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::keysyms::KEY_NoSymbol;
use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE}; use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE};
use smithay::input::keyboard::{Keysym, XkbConfig}; use smithay::input::keyboard::{Keysym, XkbConfig};
#[derive(knuffel::Decode, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Config { pub struct Config {
#[knuffel(child, default)] #[serde(default)]
pub input: Input, pub input: Input,
#[knuffel(children(name = "output"))] #[serde(default)]
pub outputs: Vec<Output>, pub output: HashMap<String, Output>,
#[knuffel(children(name = "spawn-at-startup"))] #[serde(default)]
pub spawn_at_startup: Vec<SpawnAtStartup>, pub layout: Layout,
#[knuffel(child, default)] #[serde(default)]
pub focus_ring: FocusRing, pub clients: Clients,
#[knuffel(child, default = default_border())] #[serde(default)]
pub border: FocusRing,
#[knuffel(child, default)]
pub prefer_no_csd: bool,
#[knuffel(child, default)]
pub cursor: Cursor, pub cursor: Cursor,
#[knuffel(child, unwrap(children), default)] #[serde(default)]
pub preset_column_widths: Vec<PresetWidth>, pub screenshot_ui: ScreenshotUi,
#[knuffel(child)] // Running niri without binds doesn't make much sense.
pub default_column_width: Option<DefaultColumnWidth>, pub binds: HashMap<Key, Action>,
#[knuffel(child, unwrap(argument), default = 16)] #[serde(default)]
pub gaps: u16,
#[knuffel(child, default)]
pub struts: Struts,
#[knuffel(
child,
unwrap(argument),
default = Some(String::from(
"~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
)))
]
pub screenshot_path: Option<String>,
#[knuffel(child, default)]
pub binds: Binds,
#[knuffel(child, default)]
pub debug: DebugConfig, pub debug: DebugConfig,
} }
// FIXME: Add other devices. // FIXME: Add other devices.
#[derive(knuffel::Decode, Debug, Default, PartialEq)] #[derive(Deserialize, Debug, Default, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Input { pub struct Input {
#[knuffel(child, default)]
pub keyboard: Keyboard, pub keyboard: Keyboard,
#[knuffel(child, default)]
pub touchpad: Touchpad, pub touchpad: Touchpad,
#[knuffel(child, default)]
pub tablet: Tablet, pub tablet: Tablet,
#[knuffel(child)]
pub disable_power_key_handling: bool, 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 { pub struct Keyboard {
#[knuffel(child, default)]
pub xkb: Xkb, pub xkb: Xkb,
// The defaults were chosen to match wlroots and sway.
#[knuffel(child, unwrap(argument), default = 600)]
pub repeat_delay: u16, pub repeat_delay: u16,
#[knuffel(child, unwrap(argument), default = 25)]
pub repeat_rate: u8, pub repeat_rate: u8,
#[knuffel(child, unwrap(argument), default)]
pub track_layout: TrackLayout, 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 { pub struct Xkb {
#[knuffel(child, unwrap(argument), default)]
pub rules: String, pub rules: String,
#[knuffel(child, unwrap(argument), default)]
pub model: String, pub model: String,
#[knuffel(child, unwrap(argument))] pub layout: String,
pub layout: Option<String>,
#[knuffel(child, unwrap(argument), default)]
pub variant: String, pub variant: String,
#[knuffel(child, unwrap(argument))]
pub options: Option<String>, pub options: Option<String>,
} }
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 { impl Xkb {
pub fn to_xkb_config(&self) -> XkbConfig { pub fn to_xkb_config(&self) -> XkbConfig {
XkbConfig { XkbConfig {
rules: &self.rules, rules: &self.rules,
model: &self.model, model: &self.model,
layout: self.layout.as_deref().unwrap_or("us"), layout: &self.layout,
variant: &self.variant, variant: &self.variant,
options: self.options.clone(), 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 { pub enum TrackLayout {
/// The layout change is global. /// The layout change is global.
#[default] #[default]
@@ -108,33 +108,26 @@ pub enum TrackLayout {
} }
// FIXME: Add the rest of the settings. // 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 { pub struct Touchpad {
#[knuffel(child)]
pub tap: bool, pub tap: bool,
#[knuffel(child)]
pub natural_scroll: bool, pub natural_scroll: bool,
#[knuffel(child, unwrap(argument), default)]
pub accel_speed: f64, pub accel_speed: f64,
} }
#[derive(knuffel::Decode, Debug, Default, PartialEq)] #[derive(Deserialize, Debug, Default, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Tablet { pub struct Tablet {
#[knuffel(child, unwrap(argument))]
pub map_to_output: Option<String>, pub map_to_output: Option<String>,
} }
#[derive(knuffel::Decode, Debug, Clone, PartialEq)] #[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Output { pub struct Output {
#[knuffel(child)]
pub off: bool, pub off: bool,
#[knuffel(argument)]
pub name: String,
#[knuffel(child, unwrap(argument), default = 1.)]
pub scale: f64, pub scale: f64,
#[knuffel(child)]
pub position: Option<Position>, pub position: Option<Position>,
#[knuffel(child, unwrap(argument, str))]
pub mode: Option<Mode>, pub mode: Option<Mode>,
} }
@@ -142,7 +135,6 @@ impl Default for Output {
fn default() -> Self { fn default() -> Self {
Self { Self {
off: false, off: false,
name: String::new(),
scale: 1., scale: 1.,
position: None, position: None,
mode: None, mode: None,
@@ -150,36 +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 { pub struct Position {
#[knuffel(property)]
pub x: i32, pub x: i32,
#[knuffel(property)]
pub y: i32, pub y: i32,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(DeserializeFromStr, Debug, Clone, PartialEq)]
pub struct Mode { pub struct Mode {
pub width: u16, pub width: u16,
pub height: u16, pub height: u16,
pub refresh: Option<f64>, pub refresh: Option<f64>,
} }
#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] #[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct SpawnAtStartup { #[serde(deny_unknown_fields, default)]
#[knuffel(arguments)] pub struct Layout {
pub command: Vec<String>, pub focus_ring: FocusRing,
pub border: FocusRing,
pub preset_column_widths: Vec<PresetWidth>,
// TODO
pub default_column_width: Option<PresetWidth>,
pub gaps: u16,
pub struts: Struts,
} }
#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] 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(Deserialize, Debug, Clone, Copy, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct FocusRing { pub struct FocusRing {
#[knuffel(child)]
pub off: bool, pub off: bool,
#[knuffel(child, unwrap(argument), default = 4)]
pub width: u16, pub width: u16,
#[knuffel(child, default = Color::new(127, 200, 255, 255))]
pub active_color: Color, pub active_color: Color,
#[knuffel(child, default = Color::new(80, 80, 80, 255))]
pub inactive_color: Color, pub inactive_color: Color,
} }
@@ -203,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 { pub struct Color {
#[knuffel(argument)]
pub r: u8, pub r: u8,
#[knuffel(argument)]
pub g: u8, pub g: u8,
#[knuffel(argument)]
pub b: u8, pub b: u8,
#[knuffel(argument)]
pub a: u8, pub a: u8,
} }
@@ -227,11 +235,30 @@ impl From<Color> for [f32; 4] {
} }
} }
#[derive(knuffel::Decode, Debug, PartialEq)] 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 {
pub prefer_no_csd: bool,
pub spawn_at_startup: Vec<SpawnAtStartup>,
}
#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct SpawnAtStartup {
pub command: Vec<String>,
}
#[derive(Deserialize, Debug, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Cursor { pub struct Cursor {
#[knuffel(child, unwrap(argument), default = String::from("default"))]
pub xcursor_theme: String, pub xcursor_theme: String,
#[knuffel(child, unwrap(argument), default = 24)]
pub xcursor_size: u8, pub xcursor_size: u8,
} }
@@ -244,46 +271,48 @@ 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 { pub enum PresetWidth {
Proportion(#[knuffel(argument)] f64), Proportion(f64),
Fixed(#[knuffel(argument)] i32), Fixed(i32),
} }
#[derive(knuffel::Decode, Debug, Clone, PartialEq)] #[derive(Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct DefaultColumnWidth(#[knuffel(children)] pub Vec<PresetWidth>); #[serde(deny_unknown_fields, default)]
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct Struts { pub struct Struts {
#[knuffel(child, unwrap(argument), default)]
pub left: u16, pub left: u16,
#[knuffel(child, unwrap(argument), default)]
pub right: u16, pub right: u16,
#[knuffel(child, unwrap(argument), default)]
pub top: u16, pub top: u16,
#[knuffel(child, unwrap(argument), default)]
pub bottom: u16, pub bottom: u16,
} }
#[derive(knuffel::Decode, Debug, Default, PartialEq)] #[derive(Deserialize, Debug, PartialEq, Eq)]
pub struct Binds(#[knuffel(children)] pub Vec<Bind>); #[serde(deny_unknown_fields, default)]
pub struct ScreenshotUi {
#[derive(knuffel::Decode, Debug, PartialEq)] pub disable_saving_to_disk: bool,
pub struct Bind { pub screenshot_path: String,
#[knuffel(node_name)]
pub key: Key,
#[knuffel(children)]
pub actions: Vec<Action>,
} }
#[derive(Debug, PartialEq, Eq)] impl Default for ScreenshotUi {
fn default() -> Self {
Self {
disable_saving_to_disk: false,
screenshot_path: String::from(
"~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png",
),
}
}
}
#[derive(DeserializeFromStr, Debug, PartialEq, Eq, Hash)]
pub struct Key { pub struct Key {
pub keysym: Keysym, pub keysym: Keysym,
pub modifiers: Modifiers, pub modifiers: Modifiers,
} }
bitflags! { bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Modifiers : u8 { pub struct Modifiers : u8 {
const CTRL = 1; const CTRL = 1;
const SHIFT = 2; const SHIFT = 2;
@@ -293,18 +322,19 @@ bitflags! {
} }
} }
#[derive(knuffel::Decode, Debug, Clone, PartialEq)] #[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Action { pub enum Action {
Quit, Quit,
#[knuffel(skip)] #[serde(skip)]
ChangeVt(i32), ChangeVt(i32),
Suspend, Suspend,
PowerOffMonitors, PowerOffMonitors,
ToggleDebugTint, ToggleDebugTint,
Spawn(#[knuffel(arguments)] Vec<String>), Spawn(Vec<String>),
#[knuffel(skip)] #[serde(skip)]
ConfirmScreenshot, ConfirmScreenshot,
#[knuffel(skip)] #[serde(skip)]
CancelScreenshot, CancelScreenshot,
Screenshot, Screenshot,
ScreenshotScreen, ScreenshotScreen,
@@ -332,10 +362,10 @@ pub enum Action {
CenterColumn, CenterColumn,
FocusWorkspaceDown, FocusWorkspaceDown,
FocusWorkspaceUp, FocusWorkspaceUp,
FocusWorkspace(#[knuffel(argument)] u8), FocusWorkspace(u8),
MoveWindowToWorkspaceDown, MoveWindowToWorkspaceDown,
MoveWindowToWorkspaceUp, MoveWindowToWorkspaceUp,
MoveWindowToWorkspace(#[knuffel(argument)] u8), MoveWindowToWorkspace(u8),
MoveWorkspaceDown, MoveWorkspaceDown,
MoveWorkspaceUp, MoveWorkspaceUp,
FocusMonitorLeft, FocusMonitorLeft,
@@ -346,14 +376,14 @@ pub enum Action {
MoveWindowToMonitorRight, MoveWindowToMonitorRight,
MoveWindowToMonitorDown, MoveWindowToMonitorDown,
MoveWindowToMonitorUp, MoveWindowToMonitorUp,
SetWindowHeight(#[knuffel(argument, str)] SizeChange), SetWindowHeight(SizeChange),
SwitchPresetColumnWidth, SwitchPresetColumnWidth,
MaximizeColumn, MaximizeColumn,
SetColumnWidth(#[knuffel(argument, str)] SizeChange), SetColumnWidth(SizeChange),
SwitchLayout(#[knuffel(argument)] LayoutAction), SwitchLayout(LayoutAction),
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(DeserializeFromStr, Debug, Clone, Copy, PartialEq)]
pub enum SizeChange { pub enum SizeChange {
SetFixed(i32), SetFixed(i32),
SetProportion(f64), SetProportion(f64),
@@ -361,27 +391,22 @@ pub enum SizeChange {
AdjustProportion(f64), AdjustProportion(f64),
} }
#[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq)] #[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum LayoutAction { pub enum LayoutAction {
Next, Next,
Prev, Prev,
} }
#[derive(knuffel::Decode, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct DebugConfig { pub struct DebugConfig {
#[knuffel(child, unwrap(argument), default = 1.)]
pub animation_slowdown: f64, pub animation_slowdown: f64,
#[knuffel(child)]
pub dbus_interfaces_in_non_session_instances: bool, pub dbus_interfaces_in_non_session_instances: bool,
#[knuffel(child)]
pub wait_for_frame_completion_before_queueing: bool, pub wait_for_frame_completion_before_queueing: bool,
#[knuffel(child)]
pub enable_color_transformations_capability: bool, pub enable_color_transformations_capability: bool,
#[knuffel(child)]
pub enable_overlay_planes: bool, pub enable_overlay_planes: bool,
#[knuffel(child)]
pub disable_cursor_plane: bool, pub disable_cursor_plane: bool,
#[knuffel(child, unwrap(argument))]
pub render_drm_device: Option<PathBuf>, pub render_drm_device: Option<PathBuf>,
} }
@@ -400,67 +425,55 @@ impl Default for DebugConfig {
} }
impl Config { impl Config {
pub fn load(path: Option<PathBuf>) -> miette::Result<(Self, PathBuf)> { pub fn load(path: Option<PathBuf>) -> anyhow::Result<(Self, PathBuf)> {
let path = if let Some(path) = path { let path = if let Some(path) = path {
path path
} else { } else {
let mut path = ProjectDirs::from("", "", "niri") let mut path = ProjectDirs::from("", "", "niri")
.ok_or_else(|| miette!("error retrieving home directory"))? .context("error retrieving home directory")?
.config_dir() .config_dir()
.to_owned(); .to_owned();
path.push("config.kdl"); path.push("config.kdl");
path path
}; };
let contents = std::fs::read_to_string(&path) let contents =
.into_diagnostic() std::fs::read_to_string(&path).with_context(|| format!("error reading {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:?}"); debug!("loaded config from {path:?}");
Ok((config, path)) Ok((config, path))
} }
pub fn parse(filename: &str, text: &str) -> Result<Self, knuffel::Error> { pub fn parse(text: &str) -> Result<Self, toml::de::Error> {
knuffel::parse(filename, text) toml::from_str(text)
} }
} }
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Config::parse( Config::parse(include_str!("../resources/default-config.kdl"))
"default-config.kdl", .context("error parsing default config")
include_str!("../resources/default-config.kdl"),
)
.unwrap() .unwrap()
} }
} }
impl FromStr for Mode { impl FromStr for Mode {
type Err = miette::Error; type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let Some((width, rest)) = s.split_once('x') else { let (width, rest) = s.split_once('x').context("no 'x' separator found")?;
return Err(miette!("no 'x' separator found"));
};
let (height, refresh) = match rest.split_once('@') { let (height, refresh) = match rest.split_once('@') {
Some((height, refresh)) => (height, Some(refresh)), Some((height, refresh)) => (height, Some(refresh)),
None => (rest, None), None => (rest, None),
}; };
let width = width let width = width.parse().context("error parsing width")?;
.parse() let height = height.parse().context("error parsing height")?;
.into_diagnostic()
.context("error parsing width")?;
let height = height
.parse()
.into_diagnostic()
.context("error parsing height")?;
let refresh = refresh let refresh = refresh
.map(str::parse) .map(str::parse)
.transpose() .transpose()
.into_diagnostic()
.context("error parsing refresh rate")?; .context("error parsing refresh rate")?;
Ok(Self { Ok(Self {
@@ -472,7 +485,7 @@ impl FromStr for Mode {
} }
impl FromStr for Key { impl FromStr for Key {
type Err = miette::Error; type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut modifiers = Modifiers::empty(); let mut modifiers = Modifiers::empty();
@@ -493,13 +506,13 @@ impl FromStr for Key {
} else if part.eq_ignore_ascii_case("super") || part.eq_ignore_ascii_case("win") { } else if part.eq_ignore_ascii_case("super") || part.eq_ignore_ascii_case("win") {
modifiers |= Modifiers::SUPER; modifiers |= Modifiers::SUPER;
} else { } else {
return Err(miette!("invalid modifier: {part}")); bail!("invalid modifier: {part}");
} }
} }
let keysym = keysym_from_name(key, KEYSYM_CASE_INSENSITIVE); let keysym = keysym_from_name(key, KEYSYM_CASE_INSENSITIVE);
if keysym.raw() == KEY_NoSymbol { if keysym.raw() == KEY_NoSymbol {
return Err(miette!("invalid key: {key}")); bail!("invalid key: {key}");
} }
Ok(Key { keysym, modifiers }) Ok(Key { keysym, modifiers })
@@ -507,51 +520,39 @@ impl FromStr for Key {
} }
impl FromStr for SizeChange { impl FromStr for SizeChange {
type Err = miette::Error; type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.split_once('%') { match s.split_once('%') {
Some((value, empty)) => { Some((value, empty)) => {
if !empty.is_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() { match value.bytes().next() {
Some(b'-' | b'+') => { Some(b'-' | b'+') => {
let value = value let value = value.parse().context("error parsing value")?;
.parse()
.into_diagnostic()
.context("error parsing value")?;
Ok(Self::AdjustProportion(value)) Ok(Self::AdjustProportion(value))
} }
Some(_) => { Some(_) => {
let value = value let value = value.parse().context("error parsing value")?;
.parse()
.into_diagnostic()
.context("error parsing value")?;
Ok(Self::SetProportion(value)) Ok(Self::SetProportion(value))
} }
None => Err(miette!("value is missing")), None => bail!("value is missing"),
} }
} }
None => { None => {
let value = s; let value = s;
match value.bytes().next() { match value.bytes().next() {
Some(b'-' | b'+') => { Some(b'-' | b'+') => {
let value = value let value = value.parse().context("error parsing value")?;
.parse()
.into_diagnostic()
.context("error parsing value")?;
Ok(Self::AdjustFixed(value)) Ok(Self::AdjustFixed(value))
} }
Some(_) => { Some(_) => {
let value = value let value = value.parse().context("error parsing value")?;
.parse()
.into_diagnostic()
.context("error parsing value")?;
Ok(Self::SetFixed(value)) Ok(Self::SetFixed(value))
} }
None => Err(miette!("value is missing")), None => bail!("value is missing"),
} }
} }
} }
@@ -560,17 +561,11 @@ impl FromStr for SizeChange {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use miette::NarratableReportHandler;
use super::*; use super::*;
#[track_caller] #[track_caller]
fn check(text: &str, expected: Config) { fn check(text: &str, expected: Config) {
let _ = miette::set_hook(Box::new(|_| Box::new(NarratableReportHandler::new()))); let parsed = Config::parse(text).map_err(anyhow::Error::new).unwrap();
let parsed = Config::parse("test.kdl", text)
.map_err(miette::Report::new)
.unwrap();
assert_eq!(parsed, expected); assert_eq!(parsed, expected);
} }
@@ -578,94 +573,80 @@ mod tests {
fn parse() { fn parse() {
check( check(
r#" r#"
input { [input]
keyboard { disable_power_key_handling = true
repeat-delay 600
repeat-rate 25
track-layout "window"
xkb {
layout "us,ru"
options "grp:win_space_toggle"
}
}
touchpad { [input.keyboard]
tap repeat_delay = 600
accel-speed 0.2 repeat_rate = 25
} track_layout = 'window'
xkb.layout = 'us,ru'
xkb.options = 'grp:win_space_toggle'
tablet { [input.touchpad]
map-to-output "eDP-1" tap = true
} accel_speed = 0.2
disable-power-key-handling [input.tablet]
} map_to_output = 'eDP-1'
output "eDP-1" { [output.'eDP-1']
scale 2.0 scale = 2.0
position x=10 y=20 position = { x = 10, y = 20 }
mode "1920x1080@144" mode = '1920x1080@144'
}
spawn-at-startup "alacritty" "-e" "fish" [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 }
focus-ring { [layout.focus_ring]
width 5 width = 5
active-color 0 100 200 255 active_color = [0, 100, 200, 255]
inactive-color 255 200 100 0 inactive_color = [255, 200, 100, 0]
}
border { [layout.border]
width 3 width = 3
active-color 0 100 200 255 active_color = [0, 100, 200, 255]
inactive-color 255 200 100 0 inactive_color = [255, 200, 100, 0]
}
prefer-no-csd [clients]
prefer_no_csd = true
spawn_at_startup = [
{ command = ['alacritty', '-e', 'fish'] },
]
cursor { [cursor]
xcursor-theme "breeze_cursors" xcursor_theme = 'breeze_cursors'
xcursor-size 16 xcursor_size = 16
}
preset-column-widths { [screenshot_ui]
proportion 0.25 screenshot_path = '~/Screenshots/screenshot.png'
proportion 0.5 disable_saving_to_disk = true
fixed 960
fixed 1280
}
default-column-width { proportion 0.25; } [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 }
gaps 8 [debug]
animation_slowdown = 2.0
struts { render_drm_device = '/dev/dri/renderD129'
left 1
right 2
top 3
}
screenshot-path "~/Screenshots/screenshot.png"
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"
}
"#, "#,
Config { Config {
input: Input { input: Input {
keyboard: Keyboard { keyboard: Keyboard {
xkb: Xkb { xkb: Xkb {
layout: Some("us,ru".to_owned()), layout: "us,ru".to_owned(),
options: Some("grp:win_space_toggle".to_owned()), options: Some("grp:win_space_toggle".to_owned()),
..Default::default() ..Default::default()
}, },
@@ -683,9 +664,10 @@ mod tests {
}, },
disable_power_key_handling: true, disable_power_key_handling: true,
}, },
outputs: vec![Output { output: HashMap::from([(
"eDP-1".to_owned(),
Output {
off: false, off: false,
name: "eDP-1".to_owned(),
scale: 2., scale: 2.,
position: Some(Position { x: 10, y: 20 }), position: Some(Position { x: 10, y: 20 }),
mode: Some(Mode { mode: Some(Mode {
@@ -693,10 +675,9 @@ mod tests {
height: 1080, height: 1080,
refresh: Some(144.), refresh: Some(144.),
}), }),
}], },
spawn_at_startup: vec![SpawnAtStartup { )]),
command: vec!["alacritty".to_owned(), "-e".to_owned(), "fish".to_owned()], layout: Layout {
}],
focus_ring: FocusRing { focus_ring: FocusRing {
off: false, off: false,
width: 5, width: 5,
@@ -729,18 +710,13 @@ mod tests {
a: 0, a: 0,
}, },
}, },
prefer_no_csd: true,
cursor: Cursor {
xcursor_theme: String::from("breeze_cursors"),
xcursor_size: 16,
},
preset_column_widths: vec![ preset_column_widths: vec![
PresetWidth::Proportion(0.25), PresetWidth::Proportion(0.25),
PresetWidth::Proportion(0.5), PresetWidth::Proportion(0.5),
PresetWidth::Fixed(960), PresetWidth::Fixed(960),
PresetWidth::Fixed(1280), PresetWidth::Fixed(1280),
], ],
default_column_width: Some(DefaultColumnWidth(vec![PresetWidth::Proportion(0.25)])), default_column_width: Some(PresetWidth::Proportion(0.25)),
gaps: 8, gaps: 8,
struts: Struts { struts: Struts {
left: 1, left: 1,
@@ -748,50 +724,64 @@ mod tests {
top: 3, top: 3,
bottom: 0, bottom: 0,
}, },
screenshot_path: Some(String::from("~/Screenshots/screenshot.png")), },
binds: Binds(vec![ clients: Clients {
Bind { spawn_at_startup: vec![SpawnAtStartup {
key: Key { command: vec!["alacritty".to_owned(), "-e".to_owned(), "fish".to_owned()],
}],
prefer_no_csd: true,
},
cursor: Cursor {
xcursor_theme: String::from("breeze_cursors"),
xcursor_size: 16,
},
screenshot_ui: ScreenshotUi {
disable_saving_to_disk: true,
screenshot_path: String::from("~/Screenshots/screenshot.png"),
},
binds: HashMap::from([
(
Key {
keysym: Keysym::t, keysym: Keysym::t,
modifiers: Modifiers::COMPOSITOR, modifiers: Modifiers::COMPOSITOR,
}, },
actions: vec![Action::Spawn(vec!["alacritty".to_owned()])], Action::Spawn(vec!["alacritty".to_owned()]),
}, ),
Bind { (
key: Key { Key {
keysym: Keysym::q, keysym: Keysym::q,
modifiers: Modifiers::COMPOSITOR, modifiers: Modifiers::COMPOSITOR,
}, },
actions: vec![Action::CloseWindow], Action::CloseWindow,
}, ),
Bind { (
key: Key { Key {
keysym: Keysym::h, keysym: Keysym::h,
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT, modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
}, },
actions: vec![Action::FocusMonitorLeft], Action::FocusMonitorLeft,
}, ),
Bind { (
key: Key { Key {
keysym: Keysym::l, keysym: Keysym::l,
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL, modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL,
}, },
actions: vec![Action::MoveWindowToMonitorRight], Action::MoveWindowToMonitorRight,
}, ),
Bind { (
key: Key { Key {
keysym: Keysym::comma, keysym: Keysym::comma,
modifiers: Modifiers::COMPOSITOR, modifiers: Modifiers::COMPOSITOR,
}, },
actions: vec![Action::ConsumeWindowIntoColumn], Action::ConsumeWindowIntoColumn,
}, ),
Bind { (
key: Key { Key {
keysym: Keysym::_1, keysym: Keysym::_1,
modifiers: Modifiers::COMPOSITOR, modifiers: Modifiers::COMPOSITOR,
}, },
actions: vec![Action::FocusWorkspace(1)], Action::FocusWorkspace(1),
}, ),
]), ]),
debug: DebugConfig { debug: DebugConfig {
animation_slowdown: 2., animation_slowdown: 2.,
+3 -3
View File
@@ -39,7 +39,7 @@ impl XdgShellHandler for State {
// If the user prefers no CSD, it's a reasonable assumption that they would prefer to get // If the user prefers no CSD, it's a reasonable assumption that they would prefer to get
// rid of the various client-side rounded corners also by using the tiled state. // rid of the various client-side rounded corners also by using the tiled state.
let config = self.niri.config.borrow(); let config = self.niri.config.borrow();
if config.prefer_no_csd { if config.clients.prefer_no_csd {
window.toplevel().with_pending_state(|state| { window.toplevel().with_pending_state(|state| {
state.states.set(xdg_toplevel::State::TiledLeft); state.states.set(xdg_toplevel::State::TiledLeft);
state.states.set(xdg_toplevel::State::TiledRight); state.states.set(xdg_toplevel::State::TiledRight);
@@ -192,7 +192,7 @@ delegate_xdg_shell!(State);
impl XdgDecorationHandler for State { impl XdgDecorationHandler for State {
fn new_decoration(&mut self, toplevel: ToplevelSurface) { fn new_decoration(&mut self, toplevel: ToplevelSurface) {
let mode = if self.niri.config.borrow().prefer_no_csd { let mode = if self.niri.config.borrow().clients.prefer_no_csd {
Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) Some(zxdg_toplevel_decoration_v1::Mode::ServerSide)
} else { } else {
None None
@@ -214,7 +214,7 @@ impl XdgDecorationHandler for State {
} }
fn unset_mode(&mut self, toplevel: ToplevelSurface) { fn unset_mode(&mut self, toplevel: ToplevelSurface) {
let mode = if self.niri.config.borrow().prefer_no_csd { let mode = if self.niri.config.borrow().clients.prefer_no_csd {
Some(zxdg_toplevel_decoration_v1::Mode::ServerSide) Some(zxdg_toplevel_decoration_v1::Mode::ServerSide)
} else { } else {
None None
+13 -13
View File
@@ -1,5 +1,5 @@
use std::any::Any; use std::any::Any;
use std::collections::HashSet; use std::collections::{HashMap, HashSet};
use smithay::backend::input::{ use smithay::backend::input::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, 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::pointer_constraints::{with_pointer_constraint, PointerConstraint};
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait}; 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::niri::State;
use crate::screenshot_ui::ScreenshotUi; use crate::screenshot_ui::ScreenshotUi;
use crate::utils::{center, get_monotonic_time, spawn}; use crate::utils::{center, get_monotonic_time, spawn};
@@ -1179,7 +1179,7 @@ impl State {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn should_intercept_key( fn should_intercept_key(
suppressed_keys: &mut HashSet<u32>, suppressed_keys: &mut HashSet<u32>,
bindings: &Binds, bindings: &HashMap<Key, Action>,
comp_mod: CompositorMod, comp_mod: CompositorMod,
key_code: u32, key_code: u32,
modified: Keysym, modified: Keysym,
@@ -1235,7 +1235,7 @@ fn should_intercept_key(
} }
fn action( fn action(
bindings: &Binds, bindings: &HashMap<Key, Action>,
comp_mod: CompositorMod, comp_mod: CompositorMod,
modified: Keysym, modified: Keysym,
raw: Option<Keysym>, raw: Option<Keysym>,
@@ -1284,13 +1284,13 @@ fn action(
return None; return None;
}; };
for bind in &bindings.0 { for (key, action) in bindings {
if bind.key.keysym != raw { if key.keysym != raw {
continue; continue;
} }
if bind.key.modifiers | comp_mod == modifiers { if key.modifiers | comp_mod == modifiers {
return bind.actions.first().cloned(); return Some(action.clone());
} }
} }
@@ -1339,18 +1339,18 @@ fn allowed_during_screenshot(action: &Action) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::config::{Action, Bind, Binds, Key, Modifiers}; use crate::config::{Action, Key, Modifiers};
#[test] #[test]
fn bindings_suppress_keys() { fn bindings_suppress_keys() {
let close_keysym = Keysym::q; let close_keysym = Keysym::q;
let bindings = Binds(vec![Bind { let bindings = HashMap::from([(
key: Key { Key {
keysym: close_keysym, keysym: close_keysym,
modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL, modifiers: Modifiers::COMPOSITOR | Modifiers::CTRL,
}, },
actions: vec![Action::CloseWindow], Action::CloseWindow,
}]); )]);
let comp_mod = CompositorMod::Super; let comp_mod = CompositorMod::Super;
let mut suppressed_keys = HashSet::new(); let mut suppressed_keys = HashSet::new();
+8 -8
View File
@@ -164,7 +164,8 @@ impl Default for Options {
impl Options { impl Options {
fn from_config(config: &Config) -> Self { fn from_config(config: &Config) -> Self {
let preset_column_widths = &config.preset_column_widths; let layout = &config.layout;
let preset_column_widths = &layout.preset_column_widths;
let preset_widths = if preset_column_widths.is_empty() { let preset_widths = if preset_column_widths.is_empty() {
Options::default().preset_widths Options::default().preset_widths
@@ -178,17 +179,16 @@ impl Options {
// Missing default_column_width maps to Some(ColumnWidth::Proportion(0.5)), // Missing default_column_width maps to Some(ColumnWidth::Proportion(0.5)),
// while present, but empty, maps to None. // while present, but empty, maps to None.
let default_width = config let default_width = layout
.default_column_width .default_column_width
.as_ref() .map(|w| Some(ColumnWidth::from(w))) // TODO
.map(|w| w.0.first().copied().map(ColumnWidth::from))
.unwrap_or(Some(ColumnWidth::Proportion(0.5))); .unwrap_or(Some(ColumnWidth::Proportion(0.5)));
Self { Self {
gaps: config.gaps.into(), gaps: layout.gaps.into(),
struts: config.struts, struts: layout.struts,
focus_ring: config.focus_ring, focus_ring: layout.focus_ring,
border: config.border, border: layout.border,
preset_widths, preset_widths,
default_width, default_width,
} }
+2 -5
View File
@@ -27,12 +27,12 @@ use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use std::{env, mem}; use std::{env, mem};
use anyhow::Context;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use config::Config; use config::Config;
#[cfg(not(feature = "xdp-gnome-screencast"))] #[cfg(not(feature = "xdp-gnome-screencast"))]
use dummy_pw_utils as pw_utils; use dummy_pw_utils as pw_utils;
use git_version::git_version; use git_version::git_version;
use miette::{Context, NarratableReportHandler};
use niri::{Niri, State}; use niri::{Niri, State};
use portable_atomic::Ordering; use portable_atomic::Ordering;
use sd_notify::NotifyState; use sd_notify::NotifyState;
@@ -109,9 +109,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let _client = tracy_client::Client::start(); 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. // Handle subcommands.
if let Some(subcommand) = cli.subcommand { if let Some(subcommand) = cli.subcommand {
match subcommand { match subcommand {
@@ -138,7 +135,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}; };
animation::ANIMATION_SLOWDOWN.store(config.debug.animation_slowdown, Ordering::Relaxed); animation::ANIMATION_SLOWDOWN.store(config.debug.animation_slowdown, Ordering::Relaxed);
let spawn_at_startup = mem::take(&mut config.spawn_at_startup); let spawn_at_startup = mem::take(&mut config.clients.spawn_at_startup);
// Create the compositor. // Create the compositor.
let mut event_loop = EventLoop::try_new().unwrap(); let mut event_loop = EventLoop::try_new().unwrap();
+3 -4
View File
@@ -643,7 +643,7 @@ impl Niri {
let xdg_decoration_state = XdgDecorationState::new::<State>(&display_handle); let xdg_decoration_state = XdgDecorationState::new::<State>(&display_handle);
let kde_decoration_state = KdeDecorationState::new::<State>( let kde_decoration_state = KdeDecorationState::new::<State>(
&display_handle, &display_handle,
if config_.prefer_no_csd { if config_.clients.prefer_no_csd {
KdeDecorationsMode::Server KdeDecorationsMode::Server
} else { } else {
KdeDecorationsMode::Client KdeDecorationsMode::Client
@@ -831,9 +831,8 @@ impl Niri {
let config = self let config = self
.config .config
.borrow() .borrow()
.outputs .output
.iter() .get(&name)
.find(|o| o.name == name)
.cloned() .cloned()
.unwrap_or_default(); .unwrap_or_default();
+3 -2
View File
@@ -41,10 +41,11 @@ pub fn output_size(output: &Output) -> Size<i32, Logical> {
} }
pub fn make_screenshot_path(config: &Config) -> anyhow::Result<Option<PathBuf>> { pub fn make_screenshot_path(config: &Config) -> anyhow::Result<Option<PathBuf>> {
let Some(path) = &config.screenshot_path else { if config.screenshot_ui.disable_saving_to_disk {
return Ok(None); return Ok(None);
}; }
let path = &config.screenshot_ui.screenshot_path;
let format = CString::new(path.clone()).context("path must not contain nul bytes")?; let format = CString::new(path.clone()).context("path must not contain nul bytes")?;
let mut buf = [0u8; 2048]; let mut buf = [0u8; 2048];