can't be bothered writing a commit message
This commit is contained in:
parent
d49df0b5fa
commit
46ecea18ac
8 changed files with 362 additions and 155 deletions
259
Cargo.lock
generated
259
Cargo.lock
generated
|
|
@ -10,18 +10,18 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
@ -40,13 +40,13 @@ checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.89"
|
||||
version = "0.1.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -77,8 +77,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bread-theme"
|
||||
version = "0.7.2"
|
||||
source = "git+https://git.breadway.dev/Breadway/bread-ecosystem?tag=v0.7.2#30517f161724132cdeb658c04cf5e490be07ee73"
|
||||
version = "0.7.4"
|
||||
source = "git+https://git.breadway.dev/Breadway/bread-ecosystem?tag=v0.7.4#fcba3760387e2523edb71350f8efea3bc851b21e"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"gtk4",
|
||||
|
|
@ -108,7 +108,7 @@ dependencies = [
|
|||
"gtk4",
|
||||
"relm4",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
"thiserror 2.0.20",
|
||||
"tokio",
|
||||
"toml 0.8.23",
|
||||
"tracing",
|
||||
|
|
@ -126,7 +126,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror 2.0.18",
|
||||
"thiserror 2.0.20",
|
||||
"tiny-skia",
|
||||
"toml 0.8.23",
|
||||
"tracing",
|
||||
|
|
@ -155,22 +155,22 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
|||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.25.1"
|
||||
version = "1.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424"
|
||||
checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.11.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5"
|
||||
checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -229,9 +229,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.3.0"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8"
|
||||
checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
|
|
@ -370,11 +370,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
||||
checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"getrandom 0.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -398,9 +398,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
|
|
@ -426,9 +426,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "font-types"
|
||||
version = "0.12.1"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad67eced03f5504d9cbd3a879b5958b5c54d4e5fd794361c6eb21b05fb703411"
|
||||
checksum = "75382bc7392ef10aad10935f92fc3db36d2d4dad0e5d96d8d65e04f89a07ec39"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
|
@ -467,9 +467,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
|
||||
checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
@ -482,9 +482,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
|
||||
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
|
@ -492,15 +492,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
|
||||
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
|
||||
checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
|
@ -509,38 +509,38 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
|
||||
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
|
||||
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
|
||||
checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
|
||||
checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
|
||||
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
|
@ -623,15 +623,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
|
|
@ -695,7 +694,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -814,7 +813,7 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -896,9 +895,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.103"
|
||||
version = "0.3.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
|
||||
checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
|
|
@ -913,9 +912,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
version = "0.2.189"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
|
|
@ -925,9 +924,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
|||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.18"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
|
||||
checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
@ -1089,9 +1088,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.33"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
|
||||
checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
|
|
@ -1131,42 +1130,42 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.39.4"
|
||||
version = "0.41.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e"
|
||||
checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.46"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
||||
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "rangemap"
|
||||
version = "1.7.1"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68"
|
||||
checksum = "a611d15b50743feb4c76b7d03edcb0e64f399c26961e4efe6975bc398be6aa3d"
|
||||
|
||||
[[package]]
|
||||
name = "read-fonts"
|
||||
|
|
@ -1192,9 +1191,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.16"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
|
||||
checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
|
@ -1238,7 +1237,7 @@ checksum = "36c9dbf50a60c82375e66b61d522c936b187a11b25c0a42e91c516326ad24a4f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1318,9 +1317,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
|
|
@ -1328,29 +1327,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.150"
|
||||
version = "1.0.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
||||
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -1455,7 +1454,7 @@ dependencies = [
|
|||
"memmap2",
|
||||
"pkg-config",
|
||||
"rustix",
|
||||
"thiserror 2.0.18",
|
||||
"thiserror 2.0.20",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-csd-frame",
|
||||
|
|
@ -1522,6 +1521,17 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-locale"
|
||||
version = "0.3.2"
|
||||
|
|
@ -1540,7 +1550,7 @@ dependencies = [
|
|||
"cfg-expr",
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"toml 1.1.3+spec-1.1.0",
|
||||
"toml 1.1.4+spec-1.1.0",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
|
|
@ -1561,11 +1571,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
version = "2.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.18",
|
||||
"thiserror-impl 2.0.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1576,18 +1586,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
version = "2.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1642,9 +1652,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.53.0"
|
||||
version = "1.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee"
|
||||
checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
|
|
@ -1658,13 +1668,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.7.1"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
|
||||
checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1681,9 +1691,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.3+spec-1.1.0"
|
||||
version = "1.1.4+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
||||
checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
|
|
@ -1740,9 +1750,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
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 = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||
checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
|
||||
dependencies = [
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
|
@ -1779,7 +1789,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1905,20 +1915,11 @@ version = "0.11.1+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.4+wasi-0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.126"
|
||||
version = "0.2.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
|
||||
checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
|
|
@ -1929,9 +1930,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.126"
|
||||
version = "0.2.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
|
||||
checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
|
@ -1939,31 +1940,31 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.126"
|
||||
version = "0.2.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
|
||||
checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.126"
|
||||
version = "0.2.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
|
||||
checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d"
|
||||
checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
|
|
@ -1974,9 +1975,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.31.14"
|
||||
version = "0.31.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
|
||||
checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"rustix",
|
||||
|
|
@ -2059,9 +2060,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.10"
|
||||
version = "0.31.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a"
|
||||
checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quick-xml",
|
||||
|
|
@ -2098,7 +2099,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2109,7 +2110,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2229,17 +2230,11 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||
|
||||
[[package]]
|
||||
name = "xcursor"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b"
|
||||
checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23"
|
||||
|
||||
[[package]]
|
||||
name = "xkbcommon"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ members = ["breadlock-ui", "breadlock", "breadgreet"]
|
|||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
bread-theme = { git = "https://git.breadway.dev/Breadway/bread-ecosystem", tag = "v0.7.2" }
|
||||
bread-theme = { git = "https://git.breadway.dev/Breadway/bread-ecosystem", tag = "v0.7.4" }
|
||||
bread-utils = { git = "https://git.breadway.dev/Breadway/bread-ecosystem", tag = "v0.7.2" }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ impl SimpleComponent for App {
|
|||
spawn_greetd_actor(cmd_rx, sender.clone());
|
||||
|
||||
theme::apply();
|
||||
bread_theme::gtk::bind_window_auto(&root);
|
||||
spawn_clock_ticker(sender.clone());
|
||||
|
||||
let model = App {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub use bread_theme::{ink_on, load_palette, Palette};
|
||||
pub use bread_theme::{ink_on, load_palette, load_palette_for, Palette};
|
||||
|
||||
/// Parse a `#rrggbb` hex colour. Falls back to opaque black on malformed input
|
||||
/// (palette slots are always produced by [`bread_theme`], which guarantees
|
||||
|
|
|
|||
|
|
@ -140,8 +140,9 @@ impl KeyboardHandler for AppState {
|
|||
impl AppState {
|
||||
fn handle_key(&mut self, qh: &QueueHandle<Self>, event: KeyEvent) {
|
||||
// Ignore all input while a PAM check is in flight so a fast second
|
||||
// Enter can't race the first attempt.
|
||||
if self.auth_state == AuthState::Checking {
|
||||
// Enter can't race the first attempt, and while the unlock fade is
|
||||
// playing (auth already succeeded; surfaces stay up until it ends).
|
||||
if self.auth_state == AuthState::Checking || self.unlocking.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,12 +156,13 @@ fn run_lock() {
|
|||
let auth_tx = auth::register(&loop_handle, move |state: &mut AppState, result| {
|
||||
match result {
|
||||
Ok(()) => {
|
||||
tracing::info!("authenticated, unlocking");
|
||||
if let Some(lock) = state.session_lock.take() {
|
||||
lock.unlock();
|
||||
bread_events::emit_unlocked();
|
||||
// Keep the lock surfaces up and fade the overlay out.
|
||||
// Compositor unlock() runs only after UNLOCK_MS — dying
|
||||
// mid-fade is fail-secure (session stays locked).
|
||||
tracing::info!("authenticated, fading out");
|
||||
if state.unlocking.is_none() {
|
||||
state.unlocking = Some(std::time::Instant::now());
|
||||
}
|
||||
state.exit = true;
|
||||
}
|
||||
Err(err) => {
|
||||
match err {
|
||||
|
|
@ -217,6 +218,9 @@ fn run_lock() {
|
|||
password: zeroize::Zeroizing::new(String::with_capacity(128)),
|
||||
auth_state: AuthState::Idle,
|
||||
auth_tx,
|
||||
appear_started: None,
|
||||
unlocking: None,
|
||||
anim_timer_armed: false,
|
||||
exit: false,
|
||||
};
|
||||
|
||||
|
|
@ -272,7 +276,13 @@ fn run_lock() {
|
|||
let mut consecutive_errors = 0u32;
|
||||
while !app_state.exit {
|
||||
match event_loop.dispatch(Duration::from_millis(250), &mut app_state) {
|
||||
Ok(()) => consecutive_errors = 0,
|
||||
Ok(()) => {
|
||||
consecutive_errors = 0;
|
||||
// Backup if the 16ms anim timer failed to register: the
|
||||
// 250ms dispatch timeout (or the 1s clock tick) still
|
||||
// completes a finished unlock fade.
|
||||
app_state.complete_unlock_if_ready();
|
||||
}
|
||||
Err(err) => {
|
||||
consecutive_errors += 1;
|
||||
tracing::error!(
|
||||
|
|
|
|||
|
|
@ -9,8 +9,20 @@
|
|||
use crate::background::Background;
|
||||
use breadlock_ui::painter::{rounded_rect, tokens, TextRenderer};
|
||||
use breadlock_ui::theme::tiny_skia_color;
|
||||
use std::time::Instant;
|
||||
use tiny_skia::{Color, Paint, Pixmap};
|
||||
|
||||
/// Lock-appear duration: overlay fades in and eases up from below rest.
|
||||
pub const APPEAR_MS: u64 = 450;
|
||||
/// Unlock-fade duration: overlay fades out with a slight upward drift.
|
||||
pub const UNLOCK_MS: u64 = 400;
|
||||
/// Redraw cadence while an animation is in flight (~60 Hz).
|
||||
pub const ANIM_FRAME_MS: u64 = 16;
|
||||
|
||||
const APPEAR_SLIDE_PX: f32 = 28.0;
|
||||
const UNLOCK_DRIFT_PX: f32 = 20.0;
|
||||
const DIM_ALPHA: f32 = 0.28;
|
||||
|
||||
pub struct FrameInputs<'a> {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
|
|
@ -23,6 +35,40 @@ pub struct FrameInputs<'a> {
|
|||
/// shake in v1 — just a color/status-text indicator.
|
||||
pub failed: bool,
|
||||
pub status_text: Option<&'a str>,
|
||||
/// Raw 0..1 lock-appear progress (pre-ease). 1 is rest pose.
|
||||
pub appear_t: f32,
|
||||
/// Raw 0..1 unlock-fade progress (pre-ease). 0 when not unlocking.
|
||||
pub unlock_t: f32,
|
||||
}
|
||||
|
||||
/// Ease-out cubic. `t` is clamped to 0..1.
|
||||
pub fn ease_out_cubic(t: f32) -> f32 {
|
||||
let t = t.clamp(0.0, 1.0);
|
||||
let inv = 1.0 - t;
|
||||
1.0 - inv * inv * inv
|
||||
}
|
||||
|
||||
/// Linear 0..1 progress since `started` over `duration_ms`.
|
||||
pub fn unit_progress(started: Instant, duration_ms: u64) -> f32 {
|
||||
let dur = duration_ms as f32 / 1000.0;
|
||||
if dur <= 0.0 {
|
||||
return 1.0;
|
||||
}
|
||||
(started.elapsed().as_secs_f32() / dur).clamp(0.0, 1.0)
|
||||
}
|
||||
|
||||
/// Overlay alpha and y-offset (positive is down) from raw 0..1 progress.
|
||||
pub fn overlay_motion(appear_t: f32, unlock_t: f32) -> (f32, f32) {
|
||||
let appear = ease_out_cubic(appear_t);
|
||||
let unlock = ease_out_cubic(unlock_t);
|
||||
let alpha = (appear * (1.0 - unlock)).clamp(0.0, 1.0);
|
||||
let y = APPEAR_SLIDE_PX * (1.0 - appear) - UNLOCK_DRIFT_PX * unlock;
|
||||
(alpha, y)
|
||||
}
|
||||
|
||||
fn faded(mut color: Color, alpha: f32) -> Color {
|
||||
color.apply_opacity(alpha);
|
||||
color
|
||||
}
|
||||
|
||||
/// Composes one frame. Returns `None` only if `width`/`height` are degenerate
|
||||
|
|
@ -31,11 +77,28 @@ pub fn compose(text: &mut TextRenderer, inputs: &FrameInputs) -> Option<Pixmap>
|
|||
let mut pixmap = Pixmap::new(inputs.width, inputs.height)?;
|
||||
inputs.background.paint(&mut pixmap);
|
||||
|
||||
let (alpha, y_off) = overlay_motion(inputs.appear_t, inputs.unlock_t);
|
||||
if alpha <= 0.0 {
|
||||
return Some(pixmap);
|
||||
}
|
||||
|
||||
let (w, h) = (inputs.width as f32, inputs.height as f32);
|
||||
let surface_color = tiny_skia_color(&inputs.palette.color0);
|
||||
let accent_color = tiny_skia_color(&inputs.palette.color4);
|
||||
let on_surface = tiny_skia_color(breadlock_ui::theme::ink_on(&inputs.palette.color0));
|
||||
let red_color = tiny_skia_color(&inputs.palette.color1);
|
||||
let surface_color = faded(tiny_skia_color(&inputs.palette.color0), alpha);
|
||||
let accent_color = faded(tiny_skia_color(&inputs.palette.color4), alpha);
|
||||
let on_surface = faded(
|
||||
tiny_skia_color(breadlock_ui::theme::ink_on(&inputs.palette.color0)),
|
||||
alpha,
|
||||
);
|
||||
let red_color = faded(tiny_skia_color(&inputs.palette.color1), alpha);
|
||||
|
||||
// Translucent veil over the (static) wallpaper — fades with the chrome.
|
||||
if let Some(rect) = tiny_skia::Rect::from_xywh(0.0, 0.0, w, h) {
|
||||
let mut paint = Paint::default();
|
||||
paint.set_color(
|
||||
Color::from_rgba(0.0, 0.0, 0.0, DIM_ALPHA * alpha).unwrap_or(Color::TRANSPARENT),
|
||||
);
|
||||
pixmap.fill_rect(rect, &paint, tiny_skia::Transform::identity(), None);
|
||||
}
|
||||
|
||||
// Clock, large, centered in the upper third.
|
||||
let clock_size = 64.0;
|
||||
|
|
@ -45,16 +108,16 @@ pub fn compose(text: &mut TextRenderer, inputs: &FrameInputs) -> Option<Pixmap>
|
|||
inputs.clock_text,
|
||||
inputs.font_family,
|
||||
clock_size,
|
||||
Color::WHITE,
|
||||
faded(Color::WHITE, alpha),
|
||||
(w - clock_w) / 2.0,
|
||||
h * 0.28,
|
||||
h * 0.28 + y_off,
|
||||
);
|
||||
|
||||
// Password pill, centered; turns red while showing a failed attempt.
|
||||
let pill_w = 280.0_f32.min(w - tokens::SPACE_XL as f32 * 2.0);
|
||||
let pill_h = 48.0;
|
||||
let pill_x = (w - pill_w) / 2.0;
|
||||
let pill_y = h * 0.5;
|
||||
let pill_y = h * 0.5 + y_off;
|
||||
|
||||
if let Some(path) = rounded_rect(
|
||||
pill_x,
|
||||
|
|
@ -97,7 +160,7 @@ pub fn compose(text: &mut TextRenderer, inputs: &FrameInputs) -> Option<Pixmap>
|
|||
{
|
||||
let mut paint = Paint::default();
|
||||
paint.set_color(if inputs.failed {
|
||||
Color::WHITE
|
||||
faded(Color::WHITE, alpha)
|
||||
} else {
|
||||
accent_color
|
||||
});
|
||||
|
|
@ -172,8 +235,38 @@ mod tests {
|
|||
password_len: 0,
|
||||
failed: false,
|
||||
status_text: None,
|
||||
appear_t: 1.0,
|
||||
unlock_t: 0.0,
|
||||
};
|
||||
let pixmap = compose(&mut text, &inputs).unwrap();
|
||||
assert_eq!((pixmap.width(), pixmap.height()), (400, 300));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ease_out_cubic_bounds_and_shape() {
|
||||
assert_eq!(ease_out_cubic(0.0), 0.0);
|
||||
assert_eq!(ease_out_cubic(1.0), 1.0);
|
||||
assert_eq!(ease_out_cubic(-1.0), 0.0);
|
||||
assert_eq!(ease_out_cubic(2.0), 1.0);
|
||||
// Ease-out sits above the linear diagonal in the middle of the curve.
|
||||
assert!(ease_out_cubic(0.5) > 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_motion_appear_starts_below_and_fades_in() {
|
||||
let (a0, y0) = overlay_motion(0.0, 0.0);
|
||||
assert_eq!(a0, 0.0);
|
||||
assert!(y0 > 0.0, "clock/pill should start below rest, got y={y0}");
|
||||
|
||||
let (a1, y1) = overlay_motion(1.0, 0.0);
|
||||
assert_eq!(a1, 1.0);
|
||||
assert_eq!(y1, 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_motion_unlock_fades_out_and_drifts_up() {
|
||||
let (a, y) = overlay_motion(1.0, 1.0);
|
||||
assert_eq!(a, 0.0);
|
||||
assert!(y < 0.0, "unlock should drift up from rest, got y={y}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use smithay_client_toolkit::registry_handlers;
|
|||
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 std::time::{Duration, Instant};
|
||||
use wayland_client::protocol::{wl_keyboard, wl_output, wl_shm};
|
||||
use wayland_client::{Connection, QueueHandle};
|
||||
|
||||
|
|
@ -75,6 +75,17 @@ pub struct AppState {
|
|||
pub auth_state: AuthState,
|
||||
pub auth_tx: Sender<AuthResult>,
|
||||
|
||||
/// First-frame timestamp for the lock-appear animation. `None` until
|
||||
/// the first non-degenerate redraw so the fade starts when the surface
|
||||
/// is actually visible, not when the process starts.
|
||||
pub appear_started: Option<Instant>,
|
||||
/// Set on PAM success. While `Some`, lock surfaces stay up and the
|
||||
/// overlay fades out; compositor `unlock()` happens only after the
|
||||
/// fade completes. Dying mid-fade leaves the session locked (fail-secure).
|
||||
pub unlocking: Option<Instant>,
|
||||
/// True while a ~16ms animation timer is registered on the event loop.
|
||||
pub anim_timer_armed: bool,
|
||||
|
||||
pub exit: bool,
|
||||
}
|
||||
|
||||
|
|
@ -93,28 +104,45 @@ impl AppState {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.appear_started.is_none() {
|
||||
self.appear_started = Some(Instant::now());
|
||||
}
|
||||
|
||||
let clock_text = chrono::Local::now()
|
||||
.format(&self.config.appearance.clock.format)
|
||||
.to_string();
|
||||
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::ConfigError => Some(
|
||||
"PAM config error — check logs (breadlock service not set up correctly)"
|
||||
.to_string(),
|
||||
),
|
||||
AuthState::Idle => None,
|
||||
};
|
||||
|
||||
let appear_t = self
|
||||
.appear_started
|
||||
.map(|t| render::unit_progress(t, render::APPEAR_MS))
|
||||
.unwrap_or(0.0);
|
||||
let unlock_t = self
|
||||
.unlocking
|
||||
.map(|t| render::unit_progress(t, render::UNLOCK_MS))
|
||||
.unwrap_or(0.0);
|
||||
|
||||
let output_palette = self.palette_for_surface(surface);
|
||||
let inputs = render::FrameInputs {
|
||||
width,
|
||||
height,
|
||||
background: &self.background,
|
||||
palette: &self.palette,
|
||||
palette: &output_palette,
|
||||
font_family: &self.config.appearance.font.family,
|
||||
clock_text: &clock_text,
|
||||
password_len: self.password.len(),
|
||||
failed: matches!(self.auth_state, AuthState::Failed | AuthState::ConfigError),
|
||||
status_text: status_text.as_deref(),
|
||||
appear_t,
|
||||
unlock_t,
|
||||
};
|
||||
|
||||
let Some(pixmap) = render::compose(&mut self.text_renderer, &inputs) else {
|
||||
|
|
@ -149,6 +177,18 @@ impl AppState {
|
|||
.damage_buffer(0, 0, width as i32, height as i32);
|
||||
surface.wl_surface().commit();
|
||||
buffer.destroy();
|
||||
|
||||
self.arm_anim_if_needed(qh);
|
||||
}
|
||||
|
||||
fn palette_for_surface(&self, surface: &SessionLockSurface) -> breadlock_ui::theme::Palette {
|
||||
self.surfaces
|
||||
.iter()
|
||||
.find(|s| s.surface.wl_surface() == surface.wl_surface())
|
||||
.and_then(|s| self.output_state.info(&s.output))
|
||||
.and_then(|info| info.name)
|
||||
.map(|name| breadlock_ui::theme::load_palette_for(&name))
|
||||
.unwrap_or_else(|| self.palette.clone())
|
||||
}
|
||||
|
||||
/// Redraws every currently-configured surface — used for the clock tick
|
||||
|
|
@ -162,6 +202,73 @@ impl AppState {
|
|||
for (surface, width, height) in surfaces {
|
||||
self.redraw_surface(qh, &surface, width, height);
|
||||
}
|
||||
self.complete_unlock_if_ready();
|
||||
}
|
||||
|
||||
fn appear_in_progress(&self) -> bool {
|
||||
self.appear_started
|
||||
.map(|t| t.elapsed() < Duration::from_millis(render::APPEAR_MS))
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
fn unlock_in_progress(&self) -> bool {
|
||||
self.unlocking
|
||||
.map(|t| t.elapsed() < Duration::from_millis(render::UNLOCK_MS))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn anim_in_progress(&self) -> bool {
|
||||
self.unlocking.is_some() || self.appear_in_progress()
|
||||
}
|
||||
|
||||
/// Keep requesting frames while appear or unlock-fade is running.
|
||||
fn arm_anim_if_needed(&mut self, qh: &QueueHandle<Self>) {
|
||||
if self.anim_timer_armed || !self.anim_in_progress() {
|
||||
return;
|
||||
}
|
||||
self.anim_timer_armed = true;
|
||||
let qh = qh.clone();
|
||||
if self
|
||||
.loop_handle
|
||||
.insert_source(
|
||||
Timer::from_duration(Duration::from_millis(render::ANIM_FRAME_MS)),
|
||||
move |_, _, state| state.tick_animation(&qh),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
tracing::error!("failed to arm lock animation timer");
|
||||
self.anim_timer_armed = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_animation(&mut self, qh: &QueueHandle<Self>) -> TimeoutAction {
|
||||
self.redraw_all(qh);
|
||||
if self.unlocking.is_some() && !self.unlock_in_progress() {
|
||||
self.anim_timer_armed = false;
|
||||
TimeoutAction::Drop
|
||||
} else if self.anim_in_progress() {
|
||||
TimeoutAction::ToDuration(Duration::from_millis(render::ANIM_FRAME_MS))
|
||||
} else {
|
||||
self.anim_timer_armed = false;
|
||||
TimeoutAction::Drop
|
||||
}
|
||||
}
|
||||
|
||||
/// After the unlock fade reaches t==1, send compositor `unlock` and
|
||||
/// exit. Not called until then — dying mid-fade stays locked.
|
||||
pub fn complete_unlock_if_ready(&mut self) {
|
||||
let Some(started) = self.unlocking else {
|
||||
return;
|
||||
};
|
||||
if started.elapsed() < Duration::from_millis(render::UNLOCK_MS) {
|
||||
return;
|
||||
}
|
||||
if let Some(lock) = self.session_lock.take() {
|
||||
tracing::info!("unlock fade complete");
|
||||
lock.unlock();
|
||||
crate::bread_events::emit_unlocked();
|
||||
}
|
||||
self.exit = true;
|
||||
}
|
||||
|
||||
/// After a failed attempt, clears the "wrong password" state (and
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue