Compare commits
4 commits
bffa521f47
...
ebcc7aa841
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebcc7aa841 | ||
|
|
39238c25ad | ||
|
|
9df32b1917 | ||
|
|
38aede9126 |
13 changed files with 270 additions and 133 deletions
174
Cargo.lock
generated
174
Cargo.lock
generated
|
|
@ -57,9 +57,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.13.0"
|
||||
version = "2.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
|
||||
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
|
@ -77,7 +77,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "breadgreet"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"bread-theme",
|
||||
"breadlock-ui",
|
||||
|
|
@ -95,7 +95,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "breadlock"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"breadlock-ui",
|
||||
"chrono",
|
||||
|
|
@ -108,11 +108,12 @@ dependencies = [
|
|||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wayland-client",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "breadlock-ui"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"bread-theme",
|
||||
"chrono",
|
||||
|
|
@ -130,18 +131,18 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
|||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.25.0"
|
||||
version = "1.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
||||
checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.10.2"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
|
||||
checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -150,9 +151,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.12.0"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
|
||||
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
|
|
@ -204,9 +205,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.65"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
|
||||
checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
|
|
@ -290,9 +291,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17"
|
||||
|
||||
[[package]]
|
||||
name = "cursor-icon"
|
||||
|
|
@ -401,9 +402,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "font-types"
|
||||
version = "0.11.3"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7"
|
||||
checksum = "ad67eced03f5504d9cbd3a879b5958b5c54d4e5fd794361c6eb21b05fb703411"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
|
@ -442,9 +443,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
|
||||
checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
@ -457,9 +458,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
||||
checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
|
@ -467,15 +468,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||
checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
|
||||
checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
|
@ -484,15 +485,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
|
||||
checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
|
||||
checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -501,21 +502,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
|
||||
checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
|
||||
checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||
checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
@ -939,9 +940,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.2"
|
||||
version = "2.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
|
||||
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
|
|
@ -973,9 +974,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.2.1"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
|
||||
checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
|
|
@ -1101,7 +1102,7 @@ version = "3.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
|
||||
dependencies = [
|
||||
"toml_edit 0.25.12+spec-1.1.0",
|
||||
"toml_edit 0.25.13+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1145,12 +1146,13 @@ checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68"
|
|||
|
||||
[[package]]
|
||||
name = "read-fonts"
|
||||
version = "0.39.2"
|
||||
version = "0.41.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81"
|
||||
checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"font-types",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1166,9 +1168,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.14"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
|
@ -1251,9 +1253,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||
|
||||
[[package]]
|
||||
name = "rustybuzz"
|
||||
|
|
@ -1280,9 +1282,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.2"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
|
||||
checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
|
|
@ -1378,15 +1380,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.9"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
||||
|
||||
[[package]]
|
||||
name = "skrifa"
|
||||
version = "0.42.1"
|
||||
version = "0.44.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564"
|
||||
checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"read-fonts",
|
||||
|
|
@ -1451,9 +1453,9 @@ checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
|
|||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
|
||||
checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
|
|
@ -1461,9 +1463,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
|
@ -1476,9 +1478,9 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
|||
|
||||
[[package]]
|
||||
name = "swash"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0811b01ca2c4e8718760713911feaf4675c24f94e50530a015ec646cfb622f7c"
|
||||
checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e"
|
||||
dependencies = [
|
||||
"skrifa",
|
||||
"yazi",
|
||||
|
|
@ -1487,9 +1489,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.118"
|
||||
version = "2.0.119"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1514,7 +1516,7 @@ dependencies = [
|
|||
"cfg-expr",
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"toml 1.1.2+spec-1.1.0",
|
||||
"toml 1.1.3+spec-1.1.0",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
|
|
@ -1566,9 +1568,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
|
@ -1601,9 +1603,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.11.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
|
||||
checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
|
@ -1616,9 +1618,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.52.3"
|
||||
version = "1.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
|
||||
checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
|
|
@ -1632,9 +1634,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.7.0"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||
checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1655,9 +1657,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
version = "1.1.3+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
|
||||
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
|
|
@ -1665,7 +1667,7 @@ dependencies = [
|
|||
"toml_datetime 1.1.1+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow 1.0.3",
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1702,14 +1704,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.25.12+spec-1.1.0"
|
||||
version = "0.25.13+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7"
|
||||
checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime 1.1.1+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"winnow 1.0.3",
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1718,7 +1720,7 @@ version = "1.1.2+spec-1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||
dependencies = [
|
||||
"winnow 1.0.3",
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1729,9 +1731,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
|||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.1.1+spec-1.1.0"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
|
||||
checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
|
|
@ -2196,9 +2198,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
|
||||
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
@ -2248,7 +2250,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
name = "zeroize"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Two binaries, one workspace:
|
|||
- **`breadlock`** — locks the *already running* Hyprland session via `ext-session-lock-v1`. Drop-in for `hyprlock`.
|
||||
- **`breadgreet`** — a graphical greeter that speaks `greetd`'s own IPC protocol (the same architecture as `gtkgreet`/`regreet`). `greetd` keeps owning PAM auth, VT switching, and session launching; `breadgreet` only draws the login UI and relays the conversation. This is a deliberate choice over reimplementing a display manager from scratch — `greetd` is already installed and battle-tested.
|
||||
|
||||
Both use [`bread-theme`](https://github.com/Breadway/bread-ecosystem) for palette loading, matching the rest of the bread* ecosystem (breadbar, breadbox, bos-settings).
|
||||
Both use [`bread-theme`](https://git.breadway.dev/Breadway/bread-ecosystem) for palette loading, matching the rest of the bread* ecosystem (breadbar, breadbox, bos-settings).
|
||||
|
||||
## Architecture
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ sudo pacman -S gtk4 wayland libxkbcommon pam rust cargo
|
|||
|
||||
## Packaging
|
||||
|
||||
`packaging/arch/PKGBUILD` builds and installs both binaries plus `/etc/pam.d/breadlock`. `bakery.toml` is the bread-ecosystem package index entry.
|
||||
`packaging/arch/PKGBUILD` builds and installs both binaries plus `/etc/pam.d/breadlock`, published to the `[breadway]` pacman repo by `.forgejo/workflows/package.yml`. breadlock is pacman-only — it is not in bread-ecosystem's registry and has no `bakery.toml`; a PAM/greeter component gets installed through the package manager, not the bakery curl-script channel.
|
||||
|
||||
**Not included, by design**: this repo does not touch `/etc/greetd/config.toml`, install a lock keybind, or wire up `hypridle`. Once packaged, wiring BOS to actually use these binaries means:
|
||||
|
||||
|
|
|
|||
15
bakery.toml
15
bakery.toml
|
|
@ -1,15 +0,0 @@
|
|||
name = "breadlock"
|
||||
description = "Session locker and greetd greeter for Hyprland / Wayland"
|
||||
binaries = ["breadlock", "breadgreet"]
|
||||
system_deps = ["pam", "wayland", "libxkbcommon", "gtk4"]
|
||||
optional_system_deps = ["cage", "hyprland"]
|
||||
bread_deps = []
|
||||
|
||||
[config]
|
||||
dir = "~/.config/breadlock"
|
||||
example = "breadlock.example.toml"
|
||||
|
||||
[install]
|
||||
post_install = [
|
||||
"echo 'breadlock installed. /etc/pam.d/breadlock is installed by the package; wiring greetd (cage -s -- breadgreet) and a lock keybind/hypridle is a separate manual step.'",
|
||||
]
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "breadgreet"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Breadway <rileyhorsham@gmail.com>"]
|
||||
authors = ["Breadway <plasticbread849@gmail.com>"]
|
||||
description = "Graphical greetd greeter for Hyprland / Wayland"
|
||||
|
||||
[[bin]]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "breadlock-ui"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Breadway <rileyhorsham@gmail.com>"]
|
||||
authors = ["Breadway <plasticbread849@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
bread-theme.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "breadlock"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Breadway <rileyhorsham@gmail.com>"]
|
||||
authors = ["Breadway <plasticbread849@gmail.com>"]
|
||||
description = "Session locker for Hyprland / Wayland (ext-session-lock-v1)"
|
||||
|
||||
[[bin]]
|
||||
|
|
@ -24,6 +24,7 @@ wayland-client = "0.31"
|
|||
tiny-skia = "0.12"
|
||||
chrono = "0.4"
|
||||
pam-client2 = { version = "0.5", default-features = false }
|
||||
zeroize = { version = "1", features = ["std"] }
|
||||
serde.workspace = true
|
||||
toml.workspace = true
|
||||
tracing.workspace = true
|
||||
|
|
|
|||
|
|
@ -35,8 +35,14 @@ pub fn register<Data: 'static>(
|
|||
/// Spawns a PAM check for `username`/`password` on its own thread; the
|
||||
/// outcome arrives later as an event on the loop registered via
|
||||
/// [`register`]. `password` is moved in and dropped as soon as the PAM
|
||||
/// conversation consumes it — it is never logged.
|
||||
pub fn spawn_check(username: String, password: String, result_tx: Sender<AuthResult>) {
|
||||
/// conversation consumes it — it is never logged. It's a `Zeroizing<String>`
|
||||
/// so the buffer is wiped the moment it goes out of scope at the end of this
|
||||
/// closure, rather than just deallocated with the bytes intact.
|
||||
pub fn spawn_check(
|
||||
username: String,
|
||||
password: zeroize::Zeroizing<String>,
|
||||
result_tx: Sender<AuthResult>,
|
||||
) {
|
||||
std::thread::spawn(move || {
|
||||
let result = pam::check(&username, &password);
|
||||
let _ = result_tx.send(result);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use pam_client2::conv_mock::Conversation;
|
||||
use pam_client2::{Context, Flag};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
/// The PAM service name — matches `/etc/pam.d/breadlock`
|
||||
/// (packaging/pam.d/breadlock), which is what actually determines the auth
|
||||
|
|
@ -24,12 +25,24 @@ pub enum AuthError {
|
|||
/// `acct_mgmt` (no `open_session` — the graphical session is already open;
|
||||
/// this only re-proves who's sitting at the keyboard).
|
||||
pub fn check(username: &str, password: &str) -> Result<(), AuthError> {
|
||||
// `Conversation::with_credentials` copies `password` into its own
|
||||
// `String` field (it has to — PAM's conversation callback is invoked
|
||||
// later, synchronously, by libpam via FFI). That struct has no Drop/
|
||||
// zeroize of its own, so we reach back in and zero it explicitly below
|
||||
// before `ctx` (and the conversation it owns) is dropped.
|
||||
let conv = Conversation::with_credentials(username, password);
|
||||
let mut ctx =
|
||||
Context::new(SERVICE, Some(username), conv).map_err(|_| AuthError::ContextInit)?;
|
||||
ctx.authenticate(Flag::NONE)
|
||||
.map_err(|_| AuthError::Authenticate)?;
|
||||
ctx.acct_mgmt(Flag::NONE)
|
||||
.map_err(|_| AuthError::AccountInvalid)?;
|
||||
Ok(())
|
||||
|
||||
let result = ctx
|
||||
.authenticate(Flag::NONE)
|
||||
.map_err(|_| AuthError::Authenticate)
|
||||
.and_then(|()| {
|
||||
ctx.acct_mgmt(Flag::NONE)
|
||||
.map_err(|_| AuthError::AccountInvalid)
|
||||
});
|
||||
|
||||
ctx.conversation_mut().password.zeroize();
|
||||
|
||||
result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use smithay_client_toolkit::seat::keyboard::{
|
|||
use smithay_client_toolkit::seat::{Capability, SeatHandler, SeatState};
|
||||
use wayland_client::protocol::{wl_keyboard, wl_seat, wl_surface};
|
||||
use wayland_client::{Connection, QueueHandle};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::auth;
|
||||
use crate::state::{AppState, AuthState};
|
||||
|
|
@ -23,7 +24,27 @@ impl SeatHandler for AppState {
|
|||
capability: Capability,
|
||||
) {
|
||||
if capability == Capability::Keyboard && self.keyboard.is_none() {
|
||||
match self.seat_state.get_keyboard(qh, &seat, None) {
|
||||
// Plain `get_keyboard` never populates SCTK's internal repeat
|
||||
// timer, so `KeyboardHandler::repeat_key` below only ever fires
|
||||
// for compositors that implement server-side key repeat
|
||||
// (wl_keyboard >= v10's "repeated" pseudo key-state) themselves —
|
||||
// Hyprland does not reliably do this. `get_keyboard_with_repeat`
|
||||
// registers SCTK's own client-side repeat timer driven by the
|
||||
// compositor's `repeat_info` (delay/rate); if a compositor *does*
|
||||
// do server-side repeat it advertises `rate = 0`, which this
|
||||
// timer already treats as disabled, so the two mechanisms can't
|
||||
// double-fire.
|
||||
let repeat_qh = qh.clone();
|
||||
let loop_handle = self.loop_handle.clone();
|
||||
match self.seat_state.get_keyboard_with_repeat(
|
||||
qh,
|
||||
&seat,
|
||||
None,
|
||||
loop_handle,
|
||||
Box::new(move |state: &mut AppState, _keyboard, event| {
|
||||
state.handle_key(&repeat_qh, event);
|
||||
}),
|
||||
) {
|
||||
Ok(keyboard) => self.keyboard = Some(keyboard),
|
||||
Err(err) => tracing::error!(%err, "failed to bind keyboard"),
|
||||
}
|
||||
|
|
@ -127,11 +148,26 @@ impl AppState {
|
|||
match event.keysym {
|
||||
Keysym::Return | Keysym::KP_Enter => self.submit(),
|
||||
Keysym::BackSpace => {
|
||||
self.password.pop();
|
||||
if let Some((idx, _)) = self.password.char_indices().last() {
|
||||
// Plain `String::pop()` shrinks the logical length but
|
||||
// leaves the removed character's bytes sitting in the
|
||||
// buffer's spare capacity. Zero them explicitly before
|
||||
// truncating.
|
||||
//
|
||||
// SAFETY: `idx` comes from `char_indices()`, so it is a
|
||||
// valid char boundary; the retained prefix `[..idx]`
|
||||
// is untouched and still valid UTF-8, and we truncate to
|
||||
// exactly that boundary immediately after zeroing the
|
||||
// (now-discarded) tail.
|
||||
unsafe {
|
||||
self.password.as_mut_vec()[idx..].zeroize();
|
||||
}
|
||||
self.password.truncate(idx);
|
||||
}
|
||||
self.clear_failed_state();
|
||||
}
|
||||
Keysym::Escape => {
|
||||
self.password.clear();
|
||||
self.password.zeroize();
|
||||
self.clear_failed_state();
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -151,7 +187,7 @@ impl AppState {
|
|||
}
|
||||
|
||||
fn clear_failed_state(&mut self) {
|
||||
if self.auth_state == AuthState::Failed {
|
||||
if matches!(self.auth_state, AuthState::Failed | AuthState::ConfigError) {
|
||||
self.auth_state = AuthState::Idle;
|
||||
}
|
||||
}
|
||||
|
|
@ -161,7 +197,15 @@ impl AppState {
|
|||
return;
|
||||
}
|
||||
self.auth_state = AuthState::Checking;
|
||||
let password = std::mem::take(&mut self.password);
|
||||
// Hand ownership of the buffer to the auth thread; re-reserve
|
||||
// capacity up front so the next password typed doesn't reallocate
|
||||
// (see the `password` field doc in state.rs). The taken buffer is
|
||||
// zeroized automatically when it's dropped at the end of the PAM
|
||||
// check (`auth::spawn_check`/`pam::check`).
|
||||
let password = std::mem::replace(
|
||||
&mut self.password,
|
||||
zeroize::Zeroizing::new(String::with_capacity(128)),
|
||||
);
|
||||
auth::spawn_check(self.username.clone(), password, self.auth_tx.clone());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ impl OutputHandler for AppState {
|
|||
let lock_surface = session_lock.create_lock_surface(surface, &output, qh);
|
||||
self.surfaces.push(LockSurface {
|
||||
surface: lock_surface,
|
||||
output,
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
|
|
@ -86,11 +87,16 @@ impl OutputHandler for AppState {
|
|||
) {
|
||||
}
|
||||
|
||||
/// A monitor disappeared (unplug, or Hyprland dropping/recreating it on
|
||||
/// a mode change). Drop the lock surface tied to it — otherwise
|
||||
/// `surfaces` only ever grows across hotplug cycles and `redraw_all`
|
||||
/// keeps trying to commit to a surface whose output is gone.
|
||||
fn output_destroyed(
|
||||
&mut self,
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
_output: wl_output::WlOutput,
|
||||
output: wl_output::WlOutput,
|
||||
) {
|
||||
self.surfaces.retain(|s| s.output != output);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,24 @@ fn main() {
|
|||
state.exit = true;
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::warn!(%err, "authentication failed");
|
||||
state.auth_state = AuthState::Failed;
|
||||
match err {
|
||||
// A broken PAM setup (missing/invalid /etc/pam.d/breadlock,
|
||||
// context init failure) is a config problem, not a typo —
|
||||
// rendering it identically to "wrong password" would lock
|
||||
// the user out with zero indication of what's actually
|
||||
// wrong. Log loudly and show a distinct on-screen message.
|
||||
auth::AuthError::ContextInit => {
|
||||
tracing::error!(
|
||||
%err,
|
||||
"PAM context initialization failed — check /etc/pam.d/breadlock exists and is valid; authentication cannot succeed until this is fixed"
|
||||
);
|
||||
state.auth_state = AuthState::ConfigError;
|
||||
}
|
||||
auth::AuthError::Authenticate | auth::AuthError::AccountInvalid => {
|
||||
tracing::warn!(%err, "authentication failed");
|
||||
state.auth_state = AuthState::Failed;
|
||||
}
|
||||
}
|
||||
state.schedule_clear_failed(auth_result_qh.clone());
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +104,10 @@ fn main() {
|
|||
background,
|
||||
text_renderer: breadlock_ui::painter::TextRenderer::new(),
|
||||
username,
|
||||
password: String::new(),
|
||||
// Pre-reserve capacity so ordinary typing doesn't reallocate — a
|
||||
// reallocation leaves the old (unzeroized) backing buffer, with the
|
||||
// password bytes still in it, on the heap.
|
||||
password: zeroize::Zeroizing::new(String::with_capacity(128)),
|
||||
auth_state: AuthState::Idle,
|
||||
auth_tx,
|
||||
exit: false,
|
||||
|
|
@ -107,6 +126,7 @@ fn main() {
|
|||
let lock_surface = session_lock.create_lock_surface(surface, &output, &qh);
|
||||
app_state.surfaces.push(LockSurface {
|
||||
surface: lock_surface,
|
||||
output,
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
|
|
@ -129,15 +149,48 @@ fn main() {
|
|||
)
|
||||
.expect("failed to register the clock-tick timer");
|
||||
|
||||
// A dispatch error here is the one path that can end this process while
|
||||
// the session lock is still up: `SessionLockInner::drop` deliberately
|
||||
// does *not* send `unlock`, only `destroy` (see the crate's own doc
|
||||
// comment — "choosing not to unlock here results in us failing secure"),
|
||||
// so an abrupt exit stays fail-secure at the protocol level; the failure
|
||||
// mode is a frozen/unusable lock screen (Hyprland's "lock client
|
||||
// crashed" state), not an unlocked one. We do NOT call `.unlock()` from
|
||||
// here — doing so on an error path would make an unattended failure
|
||||
// capable of unlocking the session, i.e. turn a fail-secure bug into a
|
||||
// fail-open one. Instead: tolerate a burst of transient errors (a single
|
||||
// `dispatch()` hiccup shouldn't be fatal) and only give up, loudly, after
|
||||
// several consecutive failures.
|
||||
const MAX_CONSECUTIVE_DISPATCH_ERRORS: u32 = 5;
|
||||
let mut consecutive_errors = 0u32;
|
||||
while !app_state.exit {
|
||||
if let Err(err) = event_loop.dispatch(Duration::from_millis(250), &mut app_state) {
|
||||
tracing::error!(%err, "event loop dispatch failed");
|
||||
break;
|
||||
match event_loop.dispatch(Duration::from_millis(250), &mut app_state) {
|
||||
Ok(()) => consecutive_errors = 0,
|
||||
Err(err) => {
|
||||
consecutive_errors += 1;
|
||||
tracing::error!(
|
||||
%err,
|
||||
consecutive_errors,
|
||||
"event loop dispatch failed — session remains locked (fail-secure); \
|
||||
if this persists the lock screen may become unresponsive and require \
|
||||
a VT switch or `loginctl` to recover"
|
||||
);
|
||||
if consecutive_errors >= MAX_CONSECUTIVE_DISPATCH_ERRORS {
|
||||
tracing::error!(
|
||||
"giving up after {consecutive_errors} consecutive dispatch failures; \
|
||||
exiting WITHOUT unlocking — this is intentional (fail-secure), but \
|
||||
the screen will likely be stuck and need a VT switch to recover"
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the compositor actually receives the unlock/destroy
|
||||
// requests queued above before the process exits.
|
||||
// requests queued above (from a successful auth) before the process
|
||||
// exits. This is a no-op if we got here via the dispatch-error path
|
||||
// above, since nothing queued an unlock in that case.
|
||||
let _ = app_state.conn.roundtrip();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use smithay_client_toolkit::seat::SeatState;
|
|||
use smithay_client_toolkit::session_lock::{SessionLock, SessionLockState, SessionLockSurface};
|
||||
use smithay_client_toolkit::shm::{Shm, ShmHandler};
|
||||
use std::time::Duration;
|
||||
use wayland_client::protocol::{wl_keyboard, wl_shm};
|
||||
use wayland_client::protocol::{wl_keyboard, wl_output, wl_shm};
|
||||
use wayland_client::{Connection, QueueHandle};
|
||||
|
||||
use crate::auth::AuthResult;
|
||||
|
|
@ -18,9 +18,12 @@ use crate::config::Config;
|
|||
use crate::render;
|
||||
|
||||
/// Per-output lock surface plus the size the compositor last `configure`d it
|
||||
/// to (0x0 until the first configure arrives).
|
||||
/// to (0x0 until the first configure arrives). `output` is kept so
|
||||
/// `output_destroyed` can find and drop the surface belonging to an unplugged
|
||||
/// monitor — without it, hotplug/unplug cycles only ever grow `surfaces`.
|
||||
pub struct LockSurface {
|
||||
pub surface: SessionLockSurface,
|
||||
pub output: wl_output::WlOutput,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
|
@ -31,7 +34,16 @@ pub enum AuthState {
|
|||
/// A PAM check is running on its own thread; input is ignored until it
|
||||
/// resolves so a second Enter can't race the first attempt.
|
||||
Checking,
|
||||
/// The password (or account state) was rejected by PAM — an ordinary
|
||||
/// wrong-password/locked-account outcome the user can retry.
|
||||
Failed,
|
||||
/// PAM itself failed to initialize (e.g. `/etc/pam.d/breadlock` is
|
||||
/// missing or unreadable) — this is a config/deployment problem, not
|
||||
/// something the user's password can fix. Rendered with a distinct
|
||||
/// message so a broken install doesn't look like an endless string of
|
||||
/// typos with no way to discover the real cause. See `main.rs`'s
|
||||
/// auth-result callback, which is the only place this is set.
|
||||
ConfigError,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
|
|
@ -53,7 +65,13 @@ pub struct AppState {
|
|||
pub text_renderer: breadlock_ui::painter::TextRenderer,
|
||||
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
/// Wrapped in `Zeroizing` so the buffer is wiped on every drop/replace
|
||||
/// (e.g. when `submit()` swaps in a fresh one) rather than just
|
||||
/// deallocated with the password bytes left sitting in freed heap
|
||||
/// memory. Individual edits (backspace, clear) still need their own
|
||||
/// explicit zeroing — see `input/keyboard.rs` — since `Zeroizing` only
|
||||
/// hooks `Drop`, not in-place mutation.
|
||||
pub password: zeroize::Zeroizing<String>,
|
||||
pub auth_state: AuthState,
|
||||
pub auth_tx: Sender<AuthResult>,
|
||||
|
||||
|
|
@ -81,6 +99,9 @@ impl AppState {
|
|||
let status_text = match self.auth_state {
|
||||
AuthState::Checking => Some("Checking…".to_string()),
|
||||
AuthState::Failed => Some("Wrong password".to_string()),
|
||||
AuthState::ConfigError => {
|
||||
Some("PAM config error — check logs (breadlock service not set up correctly)".to_string())
|
||||
}
|
||||
AuthState::Idle => None,
|
||||
};
|
||||
|
||||
|
|
@ -92,7 +113,7 @@ impl AppState {
|
|||
font_family: &self.config.appearance.font.family,
|
||||
clock_text: &clock_text,
|
||||
password_len: self.password.len(),
|
||||
failed: self.auth_state == AuthState::Failed,
|
||||
failed: matches!(self.auth_state, AuthState::Failed | AuthState::ConfigError),
|
||||
status_text: status_text.as_deref(),
|
||||
};
|
||||
|
||||
|
|
@ -151,7 +172,7 @@ impl AppState {
|
|||
let _ =
|
||||
self.loop_handle
|
||||
.insert_source(Timer::from_duration(timeout), move |_, _, state| {
|
||||
if state.auth_state == AuthState::Failed {
|
||||
if matches!(state.auth_state, AuthState::Failed | AuthState::ConfigError) {
|
||||
state.auth_state = AuthState::Idle;
|
||||
state.redraw_all(&qh);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# Maintainer: Breadway <rileyhorsham@gmail.com>
|
||||
# Maintainer: Breadway <plasticbread849@gmail.com>
|
||||
|
||||
pkgname=breadlock
|
||||
pkgver=0.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Session locker and greetd greeter for Hyprland / Wayland"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/Breadway/breadlock"
|
||||
url="https://git.breadway.dev/Breadway/breadlock"
|
||||
license=('MIT')
|
||||
# Some Rust deps build vendored C/asm into static archives; makepkg's default
|
||||
# -flto=auto emits GCC LTO bitcode the Rust (lld) link cannot read, causing
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue