diff --git a/.github/workflows/nightly-release.yml b/.github/workflows/nightly-release.yml index 03ebede..c498ae1 100644 --- a/.github/workflows/nightly-release.yml +++ b/.github/workflows/nightly-release.yml @@ -14,10 +14,16 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: fetch-depth: 0 + - uses: ./.github/actions/deps + + - uses: Swatinem/rust-cache@v2 + + - uses: dtolnay/rust-toolchain@stable + - name: Set version id: version run: | @@ -26,10 +32,19 @@ jobs: VERSION=$(grep -m1 '^version =' Cargo.toml | cut -d'"' -f2) echo "VERSION=${VERSION}-nightly.$DATE.$SHA" >> $GITHUB_OUTPUT + - name: Build release binary + run: cargo build --release + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: rustlock-${{ steps.version.outputs.VERSION }} + path: target/release/rustlock + - name: Create nightly release uses: softprops/action-gh-release@v3 with: - tag_name: nightly-${{ steps.version.outputs.VERSION }} + tag_name: ${{ steps.version.outputs.VERSION }} name: Nightly Build ${{ steps.version.outputs.VERSION }} prerelease: true generate_release_notes: true diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index a400e9b..f28fed8 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -14,7 +14,7 @@ jobs: quality-checks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: ./.github/actions/deps @@ -31,9 +31,6 @@ jobs: - name: Run clippy run: cargo clippy --all-targets -- -D warnings - - name: Run unit tests (default features) - run: cargo test --quiet - - name: Run unit tests (all features) run: cargo test --all-features --quiet diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcfc4c9..b743a20 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Determine tag id: tag @@ -29,13 +29,21 @@ jobs: publish-crates: runs-on: ubuntu-latest needs: [release] - if: secrets.CARGO_REGISTRY_TOKEN != '' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 + + - uses: ./.github/actions/deps + + - uses: Swatinem/rust-cache@v2 - uses: dtolnay/rust-toolchain@stable - name: Publish to crates.io env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish + run: | + if [ -z "$CARGO_REGISTRY_TOKEN" ]; then + echo "CARGO_REGISTRY_TOKEN not set β€” skipping publish" + exit 0 + fi + cargo publish diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index fb01baa..48a5723 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -11,6 +11,14 @@ on: - 'Cargo.lock' - 'deny.toml' - '.github/workflows/security.yml' + pull_request: + branches: [main, master] + paths: + - 'Cargo.toml' + - 'Cargo.lock' + - 'deny.toml' + - '.github/workflows/security.yml' + types: [opened, synchronize, reopened] env: CARGO_TERM_COLOR: always @@ -19,7 +27,7 @@ jobs: security-audit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Install Rust uses: dtolnay/rust-toolchain@stable diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a7e9f8..1fcf2b1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,7 @@ repos: - id: check-yaml - id: check-toml - id: check-added-large-files + exclude: ^assets/ - id: check-merge-conflict - repo: local diff --git a/Cargo.lock b/Cargo.lock index 6a7cc5e..9ed3242 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arrayref" @@ -46,9 +46,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" [[package]] name = "async-broadcast" @@ -69,8 +69,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -80,8 +80,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -92,9 +92,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -108,18 +108,18 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "cexpr", "clang-sys", "itertools", "lazy_static", "lazycell", "proc-macro2", - "quote 1.0.45", + "quote", "regex", "rustc-hash 1.1.0", - "shlex", - "syn 2.0.117", + "shlex 1.3.0", + "syn 2.0.118", ] [[package]] @@ -130,15 +130,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" @@ -156,8 +156,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -168,9 +168,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "cairo-rs" @@ -178,7 +178,7 @@ version = "0.20.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e3bd0f4e25afa9cabc157908d14eeef9067d6448c49414d17b3fb55f0eadd0" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "cairo-sys-rs", "glib", "libc", @@ -201,7 +201,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "log", "polling", "rustix 0.38.44", @@ -223,12 +223,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cef5b5a1a6827c7322ae2a636368a573006b27cfa76c7ebd53e834daeaab6a" +checksum = "fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c" dependencies = [ "smallvec", "target-lexicon", @@ -262,22 +262,11 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chacha20" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" -dependencies = [ - "cfg-if", - "cpufeatures", - "rand_core 0.10.0", -] - [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "num-traits", @@ -296,9 +285,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -315,15 +304,24 @@ dependencies = [ ] [[package]] -name = "clap_derive" -version = "4.6.0" +name = "clap_complete" +version = "4.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" dependencies = [ - "heck 0.5.0", + "clap", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -347,15 +345,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -377,41 +366,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote 1.0.45", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core", - "quote 1.0.45", - "syn 1.0.109", -] - [[package]] name = "data-url" version = "0.3.2" @@ -420,35 +374,24 @@ checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" [[package]] name = "dbus" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b3aa68d7e7abee336255bd7248ea965cc393f3e70411135a6f6a4b651345d4" +checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73" dependencies = [ "libc", "libdbus-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "derive_is_enum_variant" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ac8859845146979953797f03cc5b282fb4396891807cdb3d04929a88418197" -dependencies = [ - "heck 0.3.3", - "quote 0.3.15", - "syn 0.11.11", + "windows-sys 0.61.2", ] [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -459,9 +402,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "endi" @@ -476,7 +419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e40a16955681d469ab3da85aaa6b42ff656b3c67b52e1d8d3dd36afe97fd462" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote", "syn 1.0.109", ] @@ -487,7 +430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bad30c9c0fa1aaf1ae5010dab11f1117b15d35faf62cda4bbbc53b9987950f18" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote", "syn 1.0.109", ] @@ -508,8 +451,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -558,17 +501,11 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastblur" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383bbc116936203138cc8fe615c6364790847af8985a4bf579baaa4a86dca2d" - [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fdeflate" @@ -601,18 +538,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -622,27 +547,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "from_variants" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e859c8f2057687618905dbe99fc76e836e0a69738865ef90e46fc214a41bbf2" -dependencies = [ - "from_variants_impl", -] - -[[package]] -name = "from_variants_impl" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a5e644a80e6d96b2b4910fa7993301d7b7926c045b475b62202b20a36ce69e" -dependencies = [ - "darling", - "proc-macro2", - "quote 1.0.45", - "syn 1.0.109", -] - [[package]] name = "futures-channel" version = "0.3.32" @@ -696,8 +600,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -782,16 +686,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "rand_core 0.10.0", - "wasip2", - "wasip3", ] [[package]] @@ -830,7 +731,7 @@ version = "0.20.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc4b6e352d4716d84d7dde562dd9aee2a7d48beb872dd9ece7f2d1515b2d683" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "futures-channel", "futures-core", "futures-executor", @@ -851,11 +752,11 @@ version = "0.20.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8084af62f09475a3f529b1629c10c429d7600ee1398ae12dd3bf175d74e7145" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro-crate", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -887,27 +788,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -929,9 +812,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -968,9 +851,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -988,15 +871,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -1052,12 +934,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1065,9 +948,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1078,9 +961,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1092,15 +975,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1112,15 +995,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1131,18 +1014,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "1.1.0" @@ -1156,9 +1027,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1187,14 +1058,12 @@ checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", + "hashbrown", ] [[package]] @@ -1203,16 +1072,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "itertools" version = "0.12.1" @@ -1230,11 +1089,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.91" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -1261,17 +1121,11 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.184" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libdbus-sys" @@ -1284,11 +1138,11 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "libc", "plain", "redox_syscall", @@ -1308,15 +1162,15 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru-slab" @@ -1326,9 +1180,9 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memmap2" @@ -1341,9 +1195,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -1375,9 +1229,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -1396,15 +1250,13 @@ dependencies = [ [[package]] name = "mpris" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cef955a7826b1e00e901a3652e7a895abd221fb4ab61547e7d0e4c235d7feb" +checksum = "b72fbda9340cad2ca8181eabd8b96a2d8f4386e1ac9eefcf4045fc4e97d1ab7b" dependencies = [ "dbus", - "derive_is_enum_variant", "enum-kinds", - "from_variants", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -1542,9 +1394,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "plain" @@ -1571,7 +1423,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", @@ -1594,9 +1446,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -1610,16 +1462,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -1640,24 +1482,24 @@ dependencies = [ [[package]] name = "pxfm" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" +checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f" [[package]] name = "quick-xml" -version = "0.38.4" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" dependencies = [ "memchr", ] [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -1675,14 +1517,14 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.3", + "rand", "ring", "rustc-hash 2.1.2", "rustls", @@ -1705,20 +1547,14 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "0.3.15" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -1737,23 +1573,12 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", - "rand_core 0.9.5", -] - -[[package]] -name = "rand" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" -dependencies = [ - "chacha20", - "getrandom 0.4.2", - "rand_core 0.10.0", + "rand_core", ] [[package]] @@ -1763,7 +1588,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core", ] [[package]] @@ -1775,26 +1600,20 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "rand_core" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" - [[package]] name = "redox_syscall" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -1815,9 +1634,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" @@ -1932,7 +1751,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -1945,7 +1764,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -1962,21 +1781,20 @@ dependencies = [ "calloop-wayland-source", "chrono", "clap", - "fastblur", + "clap_complete", "gdk-pixbuf", "image", "log", "mpris", "pam-client", "pangocairo", - "rand 0.10.1", "reqwest", "resvg", "serde", "smithay-client-toolkit", "tiny-skia", "tokio", - "toml 1.1.2+spec-1.1.0", + "toml", "usvg", "wayland-client", "wayland-protocols", @@ -1989,9 +1807,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "once_cell", "ring", @@ -2003,9 +1821,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", @@ -2034,12 +1852,6 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - [[package]] name = "serde" version = "1.0.228" @@ -2066,15 +1878,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -2090,8 +1902,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -2121,6 +1933,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -2133,9 +1951,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simplecss" @@ -2148,9 +1966,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" @@ -2160,9 +1978,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "smithay-client-toolkit" @@ -2170,14 +1988,14 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "bytemuck", "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", - "memmap2 0.9.10", + "memmap2 0.9.11", "pkg-config", "rustix 0.38.44", "thiserror 1.0.69", @@ -2194,9 +2012,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -2217,12 +2035,6 @@ dependencies = [ "float-cmp", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" version = "2.6.1" @@ -2239,17 +2051,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] - [[package]] name = "syn" version = "1.0.109" @@ -2257,18 +2058,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote", "unicode-ident", ] @@ -2281,15 +2082,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", -] - [[package]] name = "synstructure" version = "0.13.2" @@ -2297,28 +2089,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] name = "system-deps" -version = "7.0.7" +version = "7.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c8f33736f986f16d69b6cb8b03f55ddcad5c41acc4ccc39dd88e84aa805e7f" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" dependencies = [ "cfg-expr", - "heck 0.5.0", + "heck", "pkg-config", - "toml 0.9.12+spec-1.1.0", + "toml", "version-compare", ] [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "tempfile" @@ -2327,7 +2119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", @@ -2358,8 +2150,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -2369,8 +2161,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -2401,9 +2193,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -2426,9 +2218,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -2448,8 +2240,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -2462,42 +2254,19 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ + "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.1", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -2511,14 +2280,14 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.4+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", - "winnow 0.7.15", + "winnow", ] [[package]] @@ -2527,7 +2296,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.1", + "winnow", ] [[package]] @@ -2553,20 +2322,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -2599,8 +2368,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -2635,24 +2404,6 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "untrusted" version = "0.9.0" @@ -2701,9 +2452,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "js-sys", "serde_core", @@ -2733,18 +2484,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] @@ -2757,9 +2499,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.114" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -2770,89 +2512,51 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.64" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.114" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ - "quote 1.0.45", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.114" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.114" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.0", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "wayland-backend" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" +checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" dependencies = [ "cc", "downcast-rs", @@ -2863,11 +2567,11 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.12" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" +checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "rustix 1.1.4", "wayland-backend", "wayland-scanner", @@ -2879,16 +2583,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.12" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5864c4b5b6064b06b1e8b74ead4a98a6c45a285fe7a0e784d24735f011fdb078" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ "rustix 1.1.4", "wayland-client", @@ -2897,11 +2601,11 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.10" +version = "0.32.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2909,11 +2613,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.10" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2922,29 +2626,29 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.8" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" +checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", "quick-xml", - "quote 1.0.45", + "quote", ] [[package]] name = "wayland-sys" -version = "0.31.8" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ "pkg-config", ] [[package]] name = "web-sys" -version = "0.3.91" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -2962,9 +2666,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" dependencies = [ "rustls-pki-types", ] @@ -3022,8 +2726,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -3033,8 +2737,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -3067,7 +2771,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -3076,7 +2780,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", ] [[package]] @@ -3094,14 +2807,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -3110,42 +2840,84 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -3153,113 +2925,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.7.15" +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" - [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck 0.5.0", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.0", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid 0.2.6", - "wasmparser", -] +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xcursor" @@ -3295,9 +2985,9 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3306,21 +2996,21 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", "synstructure", ] [[package]] name = "zbus" -version = "5.14.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" +checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285" dependencies = [ "async-broadcast", "async-recursion", @@ -3340,7 +3030,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow 0.7.15", + "winnow", "zbus_macros", "zbus_names", "zvariant", @@ -3348,14 +3038,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.14.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" +checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", "zbus_names", "zvariant", "zvariant_utils", @@ -3363,67 +3053,67 @@ dependencies = [ [[package]] name = "zbus_names" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", - "winnow 0.7.15", + "winnow", "zvariant", ] [[package]] name = "zerocopy" -version = "0.8.47" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.47" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -3432,9 +3122,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -3443,13 +3133,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", ] [[package]] @@ -3466,49 +3156,49 @@ checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" [[package]] name = "zune-jpeg" -version = "0.5.13" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5f41c76397b7da451efd19915684f727d7e1d516384ca6bd0ec43ec94de23c" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core", ] [[package]] name = "zvariant" -version = "5.10.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" +checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0" dependencies = [ "endi", "enumflags2", "serde", - "winnow 0.7.15", + "winnow", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.10.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" +checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote", + "syn 2.0.118", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote", "serde", - "syn 2.0.117", - "winnow 0.7.15", + "syn 2.0.118", + "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 22cb2f7..208e9c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ cairo-rs = { version = "0.20", default-features = false, features = ["png"] } gdk-pixbuf = { version = "0.20", default-features = false, features = ["v2_40"] } pangocairo = { version = "0.20" } clap = { version = "4.6", default-features = false, features = ["derive", "std", "help", "usage", "error-context"] } +clap_complete = { version = "4.6", default-features = false } toml = { version = "1.1", default-features = false, features = ["parse", "display", "serde"] } serde = { version = "1.0", default-features = false, features = ["derive", "std"] } zeroize = "1.8" @@ -25,11 +26,9 @@ whoami = "1.6" zbus = { version = "5.14", default-features = false, features = ["tokio"] } mpris = "2.0" tokio = { version = "1.51", default-features = false, features = ["rt", "rt-multi-thread", "macros", "time", "sync"] } -rand = { version = "0.10" } reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"], optional = true } image = { version = "0.25", default-features = false, features = ["png", "jpeg"] } - fastblur = "0.1" - pam-client = "0.5" +pam-client = "0.5" calloop = "0.13" xkbcommon = "0.7" calloop-wayland-source = "0.3" diff --git a/README.md b/README.md index f35354b..a324321 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ # πŸ”’ RustLock -[![License](https://img.shields.io/badge/license-AGPL--3.0%2B-blue.svg)](https://github.com/yourusername/rustlock/blob/main/LICENSE) +[![License](https://img.shields.io/badge/license-GPL-3.0-blue.svg)](https://github.com/yourusername/rustlock/blob/main/LICENSE) [![Version](https://img.shields.io/badge/version-0.1.0-green.svg)](https://github.com/yourusername/rustlock/releases) A high-performance Wayland screen locker written in Rust, inspired by `swaylock-effects`. +

+ RustLock effects demo +

+ --- ## ✨ Features @@ -13,7 +17,7 @@ A high-performance Wayland screen locker written in Rust, inspired by `swaylock- - 🎨 **Visual Effects**: - Gaussian blur (configurable radius and passes) - Vignette effect (configurable base and factor) - - Pixelate, Swirl, and Melting effects + - Pixelate and Swirl effects - Smooth fade-in animation - πŸ” **Password Indicator**: - Circular ring with configurable radius and thickness @@ -123,7 +127,6 @@ Options can be provided via command line or a configuration file at `~/.config/r | `--effect-vignette :` | β€” | Vignette: base : factor (e.g., `0.5:0.5`) | | `--effect-pixelate ` | β€” | Pixelate effect with block size in pixels | | `--effect-swirl ` | β€” | Swirl distortion with angle | -| `--effect-melting ` | β€” | Melting distortion with factor | | **Colors** (hex `RRGGBB[AA]`) | | | | `--ring-color ` | `#785412` | Outer ring color | | `--line-color ` | `#00000000` | Separator line color | @@ -135,14 +138,14 @@ Options can be provided via command line or a configuration file at `~/.config/r | `--caps-lock-color ` | `#E5A445` | Caps lock indicator ring color | | `--caps-lock-text-color ` | `#E5A445` | Caps lock text color | | `--verifying-color ` | `#0072FF` | Verifying feedback ring color | -| `--show-caps-lock-text` | `true` | Show "CAPS" text when caps lock is active | +| `--show-caps-lock-text` | `false` | Show "CAPS" text when caps lock is active | | **Display** | | | -| `--show-media` | `true` | Show MPRIS media player information | -| `--show-battery` | `true` | Show battery status | -| `--show-network` | `true` | Show WiFi SSID and signal strength | -| `--show-bluetooth` | `true` | Show Bluetooth status | -| `--show-album-art` | `true` | Show album art for media | -| `--show-keyboard-layout` | `true` | Show keyboard layout indicator | +| `--show-media` | `false` | Show MPRIS media player information | +| `--show-battery` | `false` | Show battery status | +| `--show-network` | `false` | Show WiFi SSID and signal strength | +| `--show-bluetooth` | `false` | Show Bluetooth status | +| `--show-album-art` | `false` | Show album art for media | +| `--show-keyboard-layout` | `false` | Show keyboard layout indicator | | **Feedback & Timing** | | | | `--fade-in ` | `0.2` | Fade-in animation duration | | `--grace ` | `0` | Grace period β€” any key press unlocks within N seconds | diff --git a/assets/effects-01-pixelate-15.png b/assets/effects-01-pixelate-15.png new file mode 100644 index 0000000..b86bc85 Binary files /dev/null and b/assets/effects-01-pixelate-15.png differ diff --git a/assets/effects-02-pixelate-20.png b/assets/effects-02-pixelate-20.png new file mode 100644 index 0000000..8d09afe Binary files /dev/null and b/assets/effects-02-pixelate-20.png differ diff --git a/assets/effects-03-swirl-5.png b/assets/effects-03-swirl-5.png new file mode 100644 index 0000000..cc422ed Binary files /dev/null and b/assets/effects-03-swirl-5.png differ diff --git a/assets/effects-04-swirl-vignette.png b/assets/effects-04-swirl-vignette.png new file mode 100644 index 0000000..aee337f Binary files /dev/null and b/assets/effects-04-swirl-vignette.png differ diff --git a/assets/effects-05-blur-vignette.png b/assets/effects-05-blur-vignette.png new file mode 100644 index 0000000..169d51a Binary files /dev/null and b/assets/effects-05-blur-vignette.png differ diff --git a/assets/effects-06-blur-pixelate.png b/assets/effects-06-blur-pixelate.png new file mode 100644 index 0000000..31ccf4b Binary files /dev/null and b/assets/effects-06-blur-pixelate.png differ diff --git a/assets/effects-07-blur-vignette-swirl.png b/assets/effects-07-blur-vignette-swirl.png new file mode 100644 index 0000000..4f04038 Binary files /dev/null and b/assets/effects-07-blur-vignette-swirl.png differ diff --git a/assets/rustlock-effects.webp b/assets/rustlock-effects.webp new file mode 100644 index 0000000..e9aba10 Binary files /dev/null and b/assets/rustlock-effects.webp differ diff --git a/src/config.rs b/src/config.rs index 137b102..171f5dd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -45,6 +45,13 @@ impl fmt::Display for RingShape { } } +#[derive(Debug, Clone, Copy, PartialEq, clap::ValueEnum)] +pub enum CompletionShell { + Bash, + Fish, + Zsh, +} + #[derive(Parser, Debug, Clone, Serialize, Deserialize)] #[command(author, version, about, long_about = None)] pub struct Config { @@ -91,10 +98,6 @@ pub struct Config { #[serde(default)] pub effect_swirl: Option, - #[arg(long)] - #[serde(default)] - pub effect_melting: Option, - #[arg(long, default_value = "785412", value_parser = util::parse_hex_color)] #[serde( deserialize_with = "util::deserialize_hex_color", @@ -144,7 +147,7 @@ pub struct Config { )] pub verifying_color: (f64, f64, f64, f64), - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_caps_lock_text: bool, #[arg(long, default_value = "00000000", value_parser = util::parse_hex_color)] @@ -196,19 +199,19 @@ pub struct Config { #[arg(long, default_value = "10000")] pub auth_timeout: u64, - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_media: bool, - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_battery: bool, - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_network: bool, - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_bluetooth: bool, - #[arg(long, action = clap::ArgAction::SetTrue, default_value_t = true)] + #[arg(long, action = clap::ArgAction::SetTrue)] pub show_album_art: bool, #[arg(long, action = clap::ArgAction::SetTrue)] @@ -292,6 +295,11 @@ pub struct Config { /// Timeout (seconds) for system commands (poweroff, reboot, suspend) #[arg(long, default_value = "5")] pub command_timeout: u64, + + /// Generate shell completions for the given shell + #[arg(long, value_enum)] + #[serde(skip)] + pub completions: Option, } impl Config { @@ -299,6 +307,26 @@ impl Config { use clap::CommandFactory; let mut config = Config::parse(); + + // Handle --completions early (before config file merge so file can't inject it) + if let Some(shell) = config.completions { + use clap_complete::Shell; + let mut cmd = Config::command(); + let name = "rustlock"; + match shell { + CompletionShell::Bash => { + clap_complete::generate(Shell::Bash, &mut cmd, name, &mut std::io::stdout()) + } + CompletionShell::Fish => { + clap_complete::generate(Shell::Fish, &mut cmd, name, &mut std::io::stdout()) + } + CompletionShell::Zsh => { + clap_complete::generate(Shell::Zsh, &mut cmd, name, &mut std::io::stdout()) + } + } + std::process::exit(0); + } + let cmd = Config::command(); let matches = cmd.get_matches(); diff --git a/src/effects.rs b/src/effects.rs new file mode 100644 index 0000000..0f4cdd8 --- /dev/null +++ b/src/effects.rs @@ -0,0 +1,285 @@ +//! Visual effects for lock screen backgrounds. +//! +//! Each effect takes a `&mut ImageSurface` and processes it in-place. +//! Effects are applied in order: blur β†’ vignette β†’ pixelate β†’ swirl. + +use anyhow::{Context, Result}; +use cairo::ImageSurface; + +/// Apply a swirl effect (radial rotation around the image centre). +pub fn apply_swirl(surface: &mut ImageSurface, angle: f32) -> Result<()> { + let width = surface.width(); + let height = surface.height(); + let center_x = width as f32 / 2.0; + let center_y = height as f32 / 2.0; + let radius = center_x.min(center_y); + + let stride = surface.stride() as usize; + let mut data = vec![0u8; stride * height as usize]; + surface + .with_data(|src| data.copy_from_slice(src)) + .context("swirl: failed to read surface data")?; + let original = data.clone(); + + for y in 0..height { + for x in 0..width { + let dx = x as f32 - center_x; + let dy = y as f32 - center_y; + let d = (dx * dx + dy * dy).sqrt(); + + if d < radius { + let percent = (radius - d) / radius; + let theta = percent * percent * angle; + let s = theta.sin(); + let c = theta.cos(); + + let nx = (c * dx - s * dy + center_x) as i32; + let ny = (s * dx + c * dy + center_y) as i32; + + if nx >= 0 && nx < width && ny >= 0 && ny < height { + let src_idx = (ny as usize * stride) + (nx as usize * 4); + let dst_idx = (y as usize * stride) + (x as usize * 4); + data[dst_idx..dst_idx + 4].copy_from_slice(&original[src_idx..src_idx + 4]); + } + } + } + } + + let mut surface_data = surface + .data() + .context("swirl: failed to write surface data")?; + surface_data.copy_from_slice(&data); + Ok(()) +} + +/// Pixelate the surface. +pub fn apply_pixelate(surface: &mut ImageSurface, pixel_size: u32) -> Result<()> { + if pixel_size <= 1 { + return Ok(()); + } + + let width = surface.width(); + let height = surface.height(); + let stride = surface.stride() as usize; + let mut data = vec![0u8; stride * height as usize]; + surface + .with_data(|src| data.copy_from_slice(src)) + .context("pixelate: failed to read surface data")?; + + for y in (0..height).step_by(pixel_size as usize) { + for x in (0..width).step_by(pixel_size as usize) { + let mut r = 0u32; + let mut g = 0u32; + let mut b = 0u32; + let mut count = 0u32; + + // Average pixels in the block + for py in 0..pixel_size { + for px in 0..pixel_size { + let cur_x = x + px as i32; + let cur_y = y + py as i32; + if cur_x < width && cur_y < height { + let index = (cur_y as usize * stride) + (cur_x as usize * 4); + r += data[index] as u32; + g += data[index + 1] as u32; + b += data[index + 2] as u32; + count += 1; + } + } + } + + if count > 0 { + let r = r.checked_div(count).unwrap_or(0) as u8; + let g = g.checked_div(count).unwrap_or(0) as u8; + let b = b.checked_div(count).unwrap_or(0) as u8; + + // Fill the block + for py in 0..pixel_size { + for px in 0..pixel_size { + let cur_x = x + px as i32; + let cur_y = y + py as i32; + if cur_x < width && cur_y < height { + let index = (cur_y as usize * stride) + (cur_x as usize * 4); + data[index] = r; + data[index + 1] = g; + data[index + 2] = b; + } + } + } + } + } + } + + let mut surface_data = surface + .data() + .context("pixelate: failed to write surface data")?; + surface_data.copy_from_slice(&data); + Ok(()) +} + +/// Apply a box blur effect (fast two-pass sliding-window implementation). +/// Uses multiply-shift to avoid slow integer division in the hot loop. +pub fn apply_blur(surface: &mut ImageSurface, radius: u32, times: u32) -> Result<()> { + if radius == 0 || times == 0 { + return Ok(()); + } + + let width = surface.width() as usize; + let height = surface.height() as usize; + let stride = surface.stride() as usize; + let r = radius as usize; + + let mut data = vec![0u8; stride * height]; + surface + .with_data(|src| data.copy_from_slice(src)) + .context("blur: failed to read surface data")?; + + let mut scratch = vec![0u8; stride * height]; + + // Precompute ceil(2^32 / c) for every possible window size c. + let max_count = (2 * r + 1).min(width.max(height)); + let factor: Vec = (0..=max_count) + .map(|c| { + if c == 0 { + 0 + } else { + (1u64 << 32).div_ceil(c as u64) as u32 + } + }) + .collect(); + + #[inline(always)] + fn div_mul(n: u32, factor: u32) -> u8 { + ((n as u64 * factor as u64) >> 32) as u8 + } + + for _ in 0..times { + // Horizontal box blur: data -> scratch + for y in 0..height { + let row = y * stride; + let init_end = r.min(width - 1); + let mut b_acc = 0u32; + let mut g_acc = 0u32; + let mut r_acc = 0u32; + for x in 0..=init_end { + let px = row + x * 4; + b_acc += data[px] as u32; + g_acc += data[px + 1] as u32; + r_acc += data[px + 2] as u32; + } + let mut count = (init_end + 1) as u32; + + for x in 0..width { + let dst = row + x * 4; + let f = factor[count as usize]; + scratch[dst] = div_mul(b_acc, f); + scratch[dst + 1] = div_mul(g_acc, f); + scratch[dst + 2] = div_mul(r_acc, f); + scratch[dst + 3] = data[dst + 3]; + + if x >= r { + let old = row + (x - r) * 4; + b_acc -= data[old] as u32; + g_acc -= data[old + 1] as u32; + r_acc -= data[old + 2] as u32; + count -= 1; + } + if x + r + 1 < width { + let new = row + (x + r + 1) * 4; + b_acc += data[new] as u32; + g_acc += data[new + 1] as u32; + r_acc += data[new + 2] as u32; + count += 1; + } + } + } + + // Vertical box blur: scratch -> data + let init_end = r.min(height - 1); + let mut b_acc = vec![0u32; width]; + let mut g_acc = vec![0u32; width]; + let mut r_acc = vec![0u32; width]; + for y in 0..=init_end { + let row = y * stride; + for x in 0..width { + let px = row + x * 4; + b_acc[x] += scratch[px] as u32; + g_acc[x] += scratch[px + 1] as u32; + r_acc[x] += scratch[px + 2] as u32; + } + } + let mut count = (init_end + 1) as u32; + + for y in 0..height { + let f = factor[count as usize]; + let dst_row = y * stride; + for x in 0..width { + let dst = dst_row + x * 4; + data[dst] = div_mul(b_acc[x], f); + data[dst + 1] = div_mul(g_acc[x], f); + data[dst + 2] = div_mul(r_acc[x], f); + } + + if y >= r { + let old_row = (y - r) * stride; + for x in 0..width { + let px = old_row + x * 4; + b_acc[x] -= scratch[px] as u32; + g_acc[x] -= scratch[px + 1] as u32; + r_acc[x] -= scratch[px + 2] as u32; + } + count -= 1; + } + if y + r + 1 < height { + let new_row = (y + r + 1) * stride; + for x in 0..width { + let px = new_row + x * 4; + b_acc[x] += scratch[px] as u32; + g_acc[x] += scratch[px + 1] as u32; + r_acc[x] += scratch[px + 2] as u32; + } + count += 1; + } + } + } + + let mut surface_data = surface.data()?; + surface_data.copy_from_slice(&data); + Ok(()) +} + +/// Apply a vignette effect (darken edges). +pub fn apply_vignette(surface: &mut ImageSurface, base: f32, factor: f32) -> Result<()> { + let width = surface.width(); + let height = surface.height(); + let center_x = width as f32 / 2.0; + let center_y = height as f32 / 2.0; + let max_distance = (center_x * center_x + center_y * center_y).sqrt(); + + let stride = surface.stride() as usize; + let mut data = vec![0u8; stride * height as usize]; + surface + .with_data(|src| data.copy_from_slice(src)) + .context("vignette: failed to read surface data")?; + + for y in 0..height { + for x in 0..width { + let dx = x as f32 - center_x; + let dy = y as f32 - center_y; + let distance = (dx * dx + dy * dy).sqrt(); + let vignette_factor = base + (1.0 - base) * (distance / max_distance).powf(factor); + + let index = (y as usize * stride) + (x as usize * 4); + for i in 0..3 { + let value = data[index + i] as f32 * vignette_factor; + data[index + i] = value.clamp(0.0, 255.0) as u8; + } + } + } + + let mut surface_data = surface + .data() + .context("vignette: failed to write surface data")?; + surface_data.copy_from_slice(&data); + Ok(()) +} diff --git a/src/lock.rs b/src/lock.rs index cedbc11..8034bc3 100644 --- a/src/lock.rs +++ b/src/lock.rs @@ -31,7 +31,8 @@ pub struct LockedSurface { /// Last clock minute (unix-minute) we rendered, to detect %H:%M rollover. last_minute: i64, ctrl_held: bool, - /// Set by clicking on the indicator ring. Persists until clicked again. + /// True while the pointer button is held on the indicator ring (hold-to-peek). + /// Cleared on button release, matching Ctrl-hold transient behavior. peek_toggled: bool, } @@ -188,18 +189,8 @@ impl LockedSurface { let buf = self.input_handler.password_buffer(); let length = self.input_handler.password_length(); if self.ctrl_held || self.peek_toggled { - log::debug!( - "LockedSurface::update: PEEK mode (ctrl={}, toggled={})", - self.ctrl_held, - self.peek_toggled - ); self.renderer.peek_password(buf.as_str()); } else { - log::debug!( - "LockedSurface::update: DOT mode (ctrl={}, toggled={})", - self.ctrl_held, - self.peek_toggled - ); self.renderer.set_password_display(length); } } @@ -316,11 +307,12 @@ impl LockedSurface { } } - /// Toggle peek mode on/off. Called when the user clicks on the indicator - /// ring. Persists until toggled again (unlike Ctrl-hold which is transient). - pub fn toggle_peek(&mut self) { - self.peek_toggled = !self.peek_toggled; - log::debug!("toggle_peek: peek_toggled = {}", self.peek_toggled); + /// Set peek mode on/off. Called when the user presses (held=true) or + /// releases (held=false) the mouse button on the indicator ring. Works + /// like Ctrl-hold β€” peek only lasts while the button is held. + pub fn set_peek_held(&mut self, held: bool) { + self.peek_toggled = held; + log::debug!("set_peek_held: peek_toggled = {}", self.peek_toggled); self.dirty = true; } } diff --git a/src/main.rs b/src/main.rs index 1a5e7d1..144be2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod auth; mod config; +mod effects; mod input; mod lock; mod render; @@ -704,8 +705,8 @@ impl PointerHandler for WaylandLock { events: &[PointerEvent], ) { for event in events { - if let PointerEventKind::Press { button, .. } = event.kind { - if button == 0x110 { + match event.kind { + PointerEventKind::Press { button: 0x110, .. } => { let (x, y) = event.position; if let Ok(lm) = self.lock_manager.lock() { for surface in &lm.surfaces { @@ -728,14 +729,13 @@ impl PointerHandler for WaylandLock { if handled { return; } - // Check indicator ring hit β€” toggle password peek + // Check indicator ring hit β€” hold to peek (like Ctrl) let cx = surface.renderer.width as f64 / 2.0; let cy = surface.renderer.height as f64 / 2.0; let r = surface.renderer.config.indicator_radius as f64; - let dx = x - cx; - let dy = y - cy; - if dx * dx + dy * dy <= r * r { - // Need to reborrow mutably for toggle + let shape = surface.renderer.config.ring_shape; + if crate::render::ring_shape::point_in_shape(cx, cy, r, shape, x, y) + { drop(lm); if let Ok(mut lm) = self.lock_manager.lock() { if let Some(s) = lm @@ -743,7 +743,7 @@ impl PointerHandler for WaylandLock { .iter_mut() .find(|s| s.matches_surface(&event.surface)) { - s.toggle_peek(); + s.set_peek_held(true); s.update(); let _ = s.commit(&mut self.pool); } @@ -754,6 +754,22 @@ impl PointerHandler for WaylandLock { } } } + PointerEventKind::Release { button: 0x110, .. } => { + if let Ok(mut lm) = self.lock_manager.lock() { + // Clear peek on ALL surfaces. Wayland button release events + // can reference a different wl_surface proxy than the press + // event (compositor-dependent pointer grab semantics), so + // matching by surface might miss the LockedSurface that has + // peek_toggled=true. Iterating every surface guarantees peek + // always ends on button release β€” matching Ctrl-hold behavior. + for surface in &mut lm.surfaces { + surface.set_peek_held(false); + surface.update(); + let _ = surface.commit(&mut self.pool); + } + } + } + _ => {} } } } diff --git a/src/render/indicator.rs b/src/render/indicator.rs index a959e74..b6cace0 100644 --- a/src/render/indicator.rs +++ b/src/render/indicator.rs @@ -85,9 +85,8 @@ impl Renderer { } if self.peeking { - log::debug!("draw_password_display: PEEKING text ({} chars)", count); // Draw each character at the same ring-perimeter positions as dots - self.context.set_font_size(11.0); + self.context.set_font_size(14.0); self.context.set_source_rgba(1.0, 1.0, 1.0, self.fade_alpha); for (i, ch) in self.password_display.chars().enumerate() { let t = (i as f64 / max_dots) + t_offset; @@ -117,9 +116,16 @@ impl Renderer { } } - // Cursor indicator (shared between peek and dot modes) + // Cursor indicator (shared between peek and dot modes). if self.fade_alpha > 0.0 { - let cursor_t = ((self.cursor_position as f64 - 0.5) / max_dots) + t_offset; + // At position 0, place the cursor squarely at the first-dot position + // (t_offset) instead of subtracting 0.5, which would push t negative + // and cause perimeter_point to wrap it to the far end of the ring. + let cursor_t = if self.cursor_position == 0 { + t_offset + } else { + ((self.cursor_position as f64 - 0.5) / max_dots) + t_offset + }; let (cx, cy) = ring_shape::perimeter_point(center_x, center_y, dot_radius, shape, cursor_t); let dx = cx - center_x; diff --git a/src/render/mod.rs b/src/render/mod.rs index 5379e56..98af526 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -21,7 +21,7 @@ macro_rules! render_try { mod feedback; mod indicator; mod media_bar; -mod ring_shape; +pub(crate) mod ring_shape; mod status_bar; pub struct Renderer { @@ -128,16 +128,11 @@ impl Renderer { } pub fn set_password_display(&mut self, length: usize) { - log::debug!("Renderer::set_password_display(length={})", length); self.password_display = ".".repeat(length); self.peeking = false; } pub fn peek_password(&mut self, password: &str) { - log::debug!( - "Renderer::peek_password(len={}, peeking=true)", - password.len() - ); self.password_display = password.to_string(); self.peeking = true; } diff --git a/src/render/ring_shape.rs b/src/render/ring_shape.rs index 478ef3e..5122804 100644 --- a/src/render/ring_shape.rs +++ b/src/render/ring_shape.rs @@ -207,6 +207,40 @@ pub(crate) fn build_fill_path( build_ring_path(ctx, cx, cy, inner_r, shape); } +/// Check whether a point `(px, py)` lies inside the shape's fill area. +/// This is used for hit‑testing (e.g. click & hold to peek) so the clickable +/// region matches what the user sees on screen. +pub(crate) fn point_in_shape(cx: f64, cy: f64, r: f64, shape: RingShape, px: f64, py: f64) -> bool { + let dx = (px - cx).abs(); + let dy = (py - cy).abs(); + match shape { + RingShape::Circle => dx * dx + dy * dy <= r * r, + RingShape::Square => dx <= r && dy <= r, + RingShape::Diamond => dx + dy <= r, + RingShape::Hexagon => { + // Regular hexagon, vertex at (r, 0), edge slopes at Β±60Β°. + // For |dx| β‰₯ r/2 the sloping edge bounds: |dy| ≀ √3 (r βˆ’ |dx|). + // For |dx| ≀ r/2 the flat top bounds: |dy| ≀ √3 r / 2. + let sqrt3 = 3.0_f64.sqrt(); + if dx >= r / 2.0 { + dy <= sqrt3 * (r - dx) + } else { + dy <= r * sqrt3 / 2.0 + } + } + RingShape::Pill => { + // Pill = centre rectangle (2r Γ— 2r) + semicircular caps of + // radius r at each end. Total width 4r, height 2r. + if dx <= r { + dy <= r + } else { + let ex = dx - r; + ex * ex + dy * dy <= r * r + } + } + } +} + /// Return the normalized `t` offset that places the first password dot at the /// visual top-centre of the shape. May be negative; callers should NOT wrap. pub(crate) fn top_centre_offset(shape: RingShape) -> f64 { diff --git a/src/screenshot.rs b/src/screenshot.rs index f67ada7..1b938a7 100644 --- a/src/screenshot.rs +++ b/src/screenshot.rs @@ -36,270 +36,17 @@ impl Screenshot { /// Apply configured visual effects to the screenshot. pub fn apply_effects(&mut self, config: &Config) -> Result<()> { if let Some((radius, times)) = config.effect_blur { - self.apply_blur(radius, times)?; + crate::effects::apply_blur(&mut self.surface, radius, times)?; } if let Some((base, factor)) = config.effect_vignette { - self.apply_vignette(base, factor)?; + crate::effects::apply_vignette(&mut self.surface, base, factor)?; } if let Some(pixel_size) = config.effect_pixelate { - self.apply_pixelate(pixel_size)?; + crate::effects::apply_pixelate(&mut self.surface, pixel_size)?; } if let Some(angle) = config.effect_swirl { - self.apply_swirl(angle)?; + crate::effects::apply_swirl(&mut self.surface, angle)?; } - if let Some(factor) = config.effect_melting { - self.apply_melting(factor)?; - } - Ok(()) - } - - /// Apply a swirl effect. - pub fn apply_swirl(&mut self, angle: f32) -> Result<()> { - let width = self.surface.width(); - let height = self.surface.height(); - let center_x = width as f32 / 2.0; - let center_y = height as f32 / 2.0; - let radius = center_x.min(center_y); - - let stride = self.surface.stride() as usize; - let mut data = vec![0u8; stride * height as usize]; - self.surface - .with_data(|src| data.copy_from_slice(src)) - .context("swirl: failed to read surface data")?; - let original = data.clone(); - - for y in 0..height { - for x in 0..width { - let dx = x as f32 - center_x; - let dy = y as f32 - center_y; - let d = (dx * dx + dy * dy).sqrt(); - - if d < radius { - let percent = (radius - d) / radius; - let theta = percent * percent * angle; - let s = theta.sin(); - let c = theta.cos(); - - let nx = (c * dx - s * dy + center_x) as i32; - let ny = (s * dx + c * dy + center_y) as i32; - - if nx >= 0 && nx < width && ny >= 0 && ny < height { - let src_idx = (ny as usize * stride) + (nx as usize * 4); - let dst_idx = (y as usize * stride) + (x as usize * 4); - data[dst_idx..dst_idx + 4].copy_from_slice(&original[src_idx..src_idx + 4]); - } - } - } - } - - let mut surface_data = self - .surface - .data() - .context("swirl: failed to write surface data")?; - surface_data.copy_from_slice(&data); - Ok(()) - } - - /// Apply a melting effect (vertical smear). - pub fn apply_melting(&mut self, factor: f32) -> Result<()> { - let width = self.surface.width(); - let height = self.surface.height(); - - let stride = self.surface.stride() as usize; - let mut data = vec![0u8; stride * height as usize]; - self.surface - .with_data(|src| data.copy_from_slice(src)) - .context("melting: failed to read surface data")?; - - use rand::RngExt; - let mut rng = rand::rng(); - - for x in 0..width { - let mut melt_amount = 0.0; - for y in 0..height { - melt_amount += rng.random_range(0.0..factor); - let src_y = (y as f32 - melt_amount).max(0.0) as i32; - - let src_idx = (src_y as usize * stride) + (x as usize * 4); - let dst_idx = (y as usize * stride) + (x as usize * 4); - - // Copy the pixel from above to create a smear - let pixel = [ - data[src_idx], - data[src_idx + 1], - data[src_idx + 2], - data[src_idx + 3], - ]; - data[dst_idx..dst_idx + 4].copy_from_slice(&pixel); - } - } - - let mut surface_data = self - .surface - .data() - .context("melting: failed to write surface data")?; - surface_data.copy_from_slice(&data); - Ok(()) - } - - /// Pixelate the surface. - pub fn apply_pixelate(&mut self, pixel_size: u32) -> Result<()> { - if pixel_size <= 1 { - return Ok(()); - } - - let width = self.surface.width(); - let height = self.surface.height(); - let stride = self.surface.stride() as usize; - let mut data = vec![0u8; stride * height as usize]; - self.surface - .with_data(|src| data.copy_from_slice(src)) - .context("pixelate: failed to read surface data")?; - - for y in (0..height).step_by(pixel_size as usize) { - for x in (0..width).step_by(pixel_size as usize) { - let mut r = 0u32; - let mut g = 0u32; - let mut b = 0u32; - let mut count = 0u32; - - // Average pixels in the block - for py in 0..pixel_size { - for px in 0..pixel_size { - let cur_x = x + px as i32; - let cur_y = y + py as i32; - if cur_x < width && cur_y < height { - let index = (cur_y as usize * stride) + (cur_x as usize * 4); - r += data[index] as u32; - g += data[index + 1] as u32; - b += data[index + 2] as u32; - count += 1; - } - } - } - - if count > 0 { - let r = r.checked_div(count).unwrap_or(0) as u8; - let g = g.checked_div(count).unwrap_or(0) as u8; - let b = b.checked_div(count).unwrap_or(0) as u8; - - // Fill the block - for py in 0..pixel_size { - for px in 0..pixel_size { - let cur_x = x + px as i32; - let cur_y = y + py as i32; - if cur_x < width && cur_y < height { - let index = (cur_y as usize * stride) + (cur_x as usize * 4); - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - } - } - } - } - } - } - - let mut surface_data = self - .surface - .data() - .context("pixelate: failed to write surface data")?; - surface_data.copy_from_slice(&data); - Ok(()) - } - - /// Apply a Gaussian blur effect. - pub fn apply_blur(&mut self, radius: u32, times: u32) -> Result<()> { - if radius == 0 || times == 0 { - return Ok(()); - } - - let width = self.surface.width() as usize; - let height = self.surface.height() as usize; - let stride = self.surface.stride() as usize; - let mut data = vec![0u8; stride * height]; - - self.surface - .with_data(|src| data.copy_from_slice(src)) - .context("blur: failed to read surface data")?; - - // Convert from stride-padded surface data to tight RgbaImage. - // Cairo stride may be larger than width*4 for alignment, so copy - // row by row to strip the padding. - let tight_stride = width * 4; - let mut tight = vec![0u8; tight_stride * height]; - for y in 0..height { - let src_off = y * stride; - let dst_off = y * tight_stride; - tight[dst_off..dst_off + tight_stride] - .copy_from_slice(&data[src_off..src_off + tight_stride]); - } - - let mut img: image::ImageBuffer, Vec> = - image::ImageBuffer::from_raw(width as u32, height as u32, tight) - .context("blur: failed to create image buffer")?; - - for _ in 0..times { - let mut rgb_data: Vec<[u8; 3]> = Vec::with_capacity(width * height); - for pixel in img.pixels() { - rgb_data.push([pixel[0], pixel[1], pixel[2]]); - } - - fastblur::gaussian_blur(&mut rgb_data, width, height, radius as f32); - - for (i, pixel) in img.pixels_mut().enumerate() { - pixel[0] = rgb_data[i][0]; - pixel[1] = rgb_data[i][1]; - pixel[2] = rgb_data[i][2]; - } - } - - // Copy back from tight buffer into stride-padded surface data - let new_data = img.into_raw(); - let mut surface_data = self.surface.data()?; - for y in 0..height { - let src_off = y * tight_stride; - let dst_off = y * stride; - surface_data[dst_off..dst_off + tight_stride] - .copy_from_slice(&new_data[src_off..src_off + tight_stride]); - } - Ok(()) - } - - /// Apply a vignette effect (darken edges). - pub fn apply_vignette(&mut self, base: f32, factor: f32) -> Result<()> { - let width = self.surface.width(); - let height = self.surface.height(); - let center_x = width as f32 / 2.0; - let center_y = height as f32 / 2.0; - let max_distance = (center_x * center_x + center_y * center_y).sqrt(); - - let stride = self.surface.stride() as usize; - let mut data = vec![0u8; stride * height as usize]; - self.surface - .with_data(|src| data.copy_from_slice(src)) - .context("vignette: failed to read surface data")?; - - for y in 0..height { - for x in 0..width { - let dx = x as f32 - center_x; - let dy = y as f32 - center_y; - let distance = (dx * dx + dy * dy).sqrt(); - let vignette_factor = base + (1.0 - base) * (distance / max_distance).powf(factor); - - let index = (y as usize * stride) + (x as usize * 4); - for i in 0..3 { - let value = data[index + i] as f32 * vignette_factor; - data[index + i] = value.clamp(0.0, 255.0) as u8; - } - } - } - - let mut surface_data = self - .surface - .data() - .context("vignette: failed to write surface data")?; - surface_data.copy_from_slice(&data); Ok(()) } }