diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4f19141..754b859e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,11 +19,11 @@ jobs: - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.93.1 + toolchain: 1.90.0 components: clippy - name: install dependencies run: sudo apt update && sudo apt install -y libxkbcommon-dev libwayland-dev libdbus-1-dev libpulse-dev libpipewire-0.3-dev libinput-dev - uses: actions-rs-plus/clippy-check@v2 with: - toolchain: 1.93.1 + toolchain: 1.90.0 args: --all --all-targets --all-features diff --git a/.zed/settings.json b/.zed/settings.json deleted file mode 100644 index 2cc7b98d..00000000 --- a/.zed/settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "format_on_save": "on", - "lsp": { - "rust-analyzer": { - "initialization_options": { - "check": { - "command": "clippy", - }, - "rustfmt": { - "extraArgs": ["+nightly"], - }, - }, - }, - }, -} diff --git a/Cargo.lock b/Cargo.lock index 6b532e54..1a265c94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "accesskit" version = "0.22.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "uuid", ] @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "accesskit_atspi_common" version = "0.15.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "accesskit_consumer", @@ -41,7 +41,7 @@ dependencies = [ [[package]] name = "accesskit_consumer" version = "0.32.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "hashbrown 0.16.1", @@ -50,7 +50,7 @@ dependencies = [ [[package]] name = "accesskit_macos" version = "0.23.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "accesskit_consumer", @@ -63,7 +63,7 @@ dependencies = [ [[package]] name = "accesskit_unix" version = "0.18.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -78,7 +78,7 @@ dependencies = [ [[package]] name = "accesskit_windows" version = "0.30.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "accesskit_consumer", @@ -91,7 +91,7 @@ dependencies = [ [[package]] name = "accesskit_winit" version = "0.30.0" -source = "git+https://github.com/wash2/accesskit?rev=6c20249#6c20249d3b9fd45e7002efad9f6b6171a9257912" +source = "git+https://github.com/wash2/accesskit?tag=cosmic-0.14#f0599eed5f18111228266fe3f28991cc48b5964f" dependencies = [ "accesskit", "accesskit_macos", @@ -107,6 +107,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.8.12" @@ -122,9 +133,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.5" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -135,12 +146,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "almost" version = "0.2.0" @@ -154,7 +159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 2.13.2", + "bitflags 2.11.0", "cc", "jni", "libc", @@ -163,7 +168,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] @@ -174,18 +179,34 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "android_system_properties" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] -name = "anyhow" -version = "1.0.104" +name = "annotate-snippets" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +dependencies = [ + "anstyle", + "unicode-width", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "apply" @@ -204,9 +225,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.9.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -219,9 +240,15 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" @@ -241,7 +268,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.5", + "rand 0.9.2", "raw-window-handle", "serde", "serde_repr", @@ -259,7 +286,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.5", + "rand 0.9.2", "serde", "serde_repr", "tokio", @@ -332,7 +359,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.5", + "rustix 1.1.4", "slab", "windows-sys 0.61.2", ] @@ -363,7 +390,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 1.1.5", + "rustix 1.1.4", ] [[package]] @@ -374,7 +401,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -389,7 +416,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.5", + "rustix 1.1.4", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -403,13 +430,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.92" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -467,21 +494,21 @@ dependencies = [ [[package]] name = "auto_enums" -version = "0.8.10" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3091d68264354f211516b91dce6f71046e444fab1867716035f736667243affb" +checksum = "65398a2893f41bce5c9259f6e1a4f03fbae40637c1bdc755b4f387f48c613b03" dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "autocfg" -version = "1.5.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -489,12 +516,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" - [[package]] name = "basic-toml" version = "0.1.10" @@ -504,6 +525,25 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "annotate-snippets", + "bitflags 2.11.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.2", + "shlex", + "syn", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -527,9 +567,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" dependencies = [ "serde_core", ] @@ -542,11 +582,20 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "block-buffer" -version = "0.12.1" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "hybrid-array", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", ] [[package]] @@ -569,9 +618,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.7.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ "async-channel", "async-task", @@ -597,7 +646,7 @@ dependencies = [ "libc", "log", "macaddr", - "nix", + "nix 0.29.0", "num-derive", "num-traits", "pin-project", @@ -611,32 +660,23 @@ dependencies = [ [[package]] name = "borsh" -version = "1.8.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ "bytes", "cfg_aliases", ] -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - [[package]] name = "bstr" -version = "1.13.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", - "serde_core", + "serde", ] [[package]] @@ -648,18 +688,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "build_helpers" -version = "0.14.0" -dependencies = [ - "cfg_aliases", -] - [[package]] name = "bumpalo" -version = "3.20.3" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "by_address" @@ -669,22 +702,22 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.25.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.12.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -695,9 +728,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.12.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "calendrical_calculations" @@ -715,9 +748,9 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "polling", - "rustix 1.1.5", + "rustix 1.1.4", "slab", "tracing", ] @@ -729,40 +762,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" dependencies = [ "calloop", - "rustix 1.1.5", + "rustix 1.1.4", "wayland-backend", "wayland-client", ] [[package]] -name = "cc" -version = "1.4.7" +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex 2.0.1", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "cfg-expr" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368" +dependencies = [ + "smallvec", + "target-lexicon", ] [[package]] name = "cfg-if" -version = "1.0.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.45" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "num-traits", @@ -770,6 +831,27 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clipboard-win" version = "5.4.1" @@ -782,6 +864,7 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "objc", "objc-foundation", @@ -791,12 +874,22 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "dnd", "mime 0.1.0", "smithay-clipboard", ] +[[package]] +name = "clipboard_x11" +version = "0.4.2" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" +dependencies = [ + "thiserror 1.0.69", + "x11rb", +] + [[package]] name = "cocoa" version = "0.25.0" @@ -846,9 +939,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.6.8" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -865,15 +958,24 @@ dependencies = [ [[package]] name = "configparser" -version = "3.3.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031ad3d167622974ed636505ae4556267ed4aa2aea0464122fa6bc9698a32825" +checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" [[package]] -name = "const-oid" -version = "0.10.2" +name = "convert_case" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie-factory" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" [[package]] name = "core-foundation" @@ -931,7 +1033,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "core-foundation 0.10.1", "libc", ] @@ -947,7 +1049,7 @@ dependencies = [ [[package]] name = "cosmic-app-list" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-app-list-config", @@ -958,11 +1060,11 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "image", - "libcosmic-yoda", - "memmap2 0.9.11", + "libcosmic", + "memmap2 0.9.10", "rust-embed", - "rustc-hash 2.1.3", - "rustix 1.1.5", + "rustc-hash 2.1.2", + "rustix 1.1.4", "switcheroo-control", "tokio", "tracing", @@ -974,15 +1076,15 @@ dependencies = [ [[package]] name = "cosmic-app-list-config" -version = "1.9.0" +version = "1.0.2" dependencies = [ - "libcosmic-yoda", + "libcosmic", "serde", ] [[package]] name = "cosmic-applet-a11y" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -991,7 +1093,7 @@ dependencies = [ "cosmic-settings-accessibility-subscription", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1001,14 +1103,12 @@ dependencies = [ [[package]] name = "cosmic-applet-audio" -version = "1.9.0" +version = "1.0.2" dependencies = [ - "cosmic-settings-audio-client", - "futures", + "cosmic-settings-sound-subscription", "i18n-embed", "i18n-embed-fl", - "intmap", - "libcosmic-yoda", + "libcosmic", "mpris2-zbus", "rust-embed", "serde", @@ -1019,25 +1119,24 @@ dependencies = [ "url", "urlencoding", "zbus", - "zlink", ] [[package]] name = "cosmic-applet-battery" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-applets-config", "cosmic-config", "cosmic-settings-daemon-subscription", "cosmic-settings-upower-subscription", - "drm", + "drm 0.14.1", "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "serde", "tokio", "tracing", @@ -1049,7 +1148,7 @@ dependencies = [ [[package]] name = "cosmic-applet-bluetooth" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "bluer", @@ -1057,9 +1156,9 @@ dependencies = [ "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "tokio", "tracing", "tracing-log", @@ -1068,14 +1167,12 @@ dependencies = [ [[package]] name = "cosmic-applet-input-sources" -version = "1.9.0" +version = "1.0.2" dependencies = [ - "cosmic-client-toolkit", "cosmic-comp-config", - "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1086,16 +1183,16 @@ dependencies = [ [[package]] name = "cosmic-applet-minimize" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "i18n-embed", "i18n-embed-fl", "image", - "libcosmic-yoda", - "memmap2 0.9.11", + "libcosmic", + "memmap2 0.9.10", "rust-embed", - "rustix 1.1.5", + "rustix 1.1.4", "tokio", "tracing", "tracing-log", @@ -1104,29 +1201,34 @@ dependencies = [ [[package]] name = "cosmic-applet-network" -version = "1.9.0" +version = "1.0.2" dependencies = [ + "anyhow", "async-fn-stream", + "cosmic-dbus-networkmanager", + "cosmic-settings-airplane-mode-subscription", + "cosmic-settings-network-manager-subscription", "futures", "futures-util", "i18n-embed", "i18n-embed-fl", - "indexmap 2.14.2", - "libcosmic-yoda", - "nmrs", + "indexmap 2.14.0", + "libcosmic", + "nm-secret-agent-manager", "rust-embed", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "secure-string", "tokio", "tracing", "tracing-log", "tracing-subscriber", "uuid", + "zbus", ] [[package]] name = "cosmic-applet-notifications" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-notifications-config", @@ -1134,7 +1236,7 @@ dependencies = [ "futures-util", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1144,27 +1246,16 @@ dependencies = [ "zbus", ] -[[package]] -name = "cosmic-applet-osk" -version = "1.9.0" -dependencies = [ - "cosmic-osk-config", - "libcosmic-yoda", - "tracing", - "tracing-log", - "tracing-subscriber", -] - [[package]] name = "cosmic-applet-power" -version = "1.9.0" +version = "1.0.2" dependencies = [ "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "logind-zbus", "rust-embed", - "rustix 1.1.5", + "rustix 1.1.4", "tokio", "tracing", "tracing-log", @@ -1174,11 +1265,11 @@ dependencies = [ [[package]] name = "cosmic-applet-status-area" -version = "1.9.0" +version = "1.0.2" dependencies = [ "futures", - "libcosmic-yoda", - "rustc-hash 2.1.3", + "libcosmic", + "rustc-hash 2.1.2", "serde", "tokio", "tracing", @@ -1189,7 +1280,7 @@ dependencies = [ [[package]] name = "cosmic-applet-tiling" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -1197,9 +1288,9 @@ dependencies = [ "cosmic-protocols", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "tokio", "tracing", "tracing-log", @@ -1208,14 +1299,14 @@ dependencies = [ [[package]] name = "cosmic-applet-time" -version = "1.9.0" +version = "1.0.2" dependencies = [ "cosmic-applets-config", "i18n-embed", "i18n-embed-fl", "icu", "jiff", - "libcosmic-yoda", + "libcosmic", "logind-zbus", "rust-embed", "timedate-zbus", @@ -1228,14 +1319,14 @@ dependencies = [ [[package]] name = "cosmic-applet-workspaces" -version = "1.9.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1245,7 +1336,7 @@ dependencies = [ [[package]] name = "cosmic-applets" -version = "1.9.0" +version = "1.0.2" dependencies = [ "cosmic-app-list", "cosmic-applet-a11y", @@ -1256,14 +1347,13 @@ dependencies = [ "cosmic-applet-minimize", "cosmic-applet-network", "cosmic-applet-notifications", - "cosmic-applet-osk", "cosmic-applet-power", "cosmic-applet-status-area", "cosmic-applet-tiling", "cosmic-applet-time", "cosmic-applet-workspaces", "cosmic-panel-button", - "libcosmic-yoda", + "libcosmic", "tracing", "tracing-log", "tracing-subscriber", @@ -1272,7 +1362,7 @@ dependencies = [ [[package]] name = "cosmic-applets-config" -version = "1.9.0" +version = "1.0.2" dependencies = [ "cosmic-config", "serde", @@ -1281,8 +1371,9 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.2.0" +source = "git+https://github.com/pop-os/cosmic-protocols//?branch=main#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cosmic-protocols", "libc", "smithay-client-toolkit", @@ -1292,7 +1383,8 @@ dependencies = [ [[package]] name = "cosmic-comp-config" -version = "1.0.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-comp.git?rev=5eb5af4#5eb5af46756f2f2bc5e812cf68fe4c4b79efd924" dependencies = [ "cosmic-config", "input", @@ -1302,6 +1394,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1311,7 +1404,7 @@ dependencies = [ "iced_futures", "known-folders", "notify", - "ron 0.12.2", + "ron 0.12.1", "serde", "tokio", "tracing", @@ -1322,35 +1415,51 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "cosmic-dbus-a11y" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "zbus", ] +[[package]] +name = "cosmic-dbus-networkmanager" +version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +dependencies = [ + "bitflags 2.11.0", + "derive_builder", + "jiff", + "procfs", + "zbus", + "zvariant", +] + [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" +source = "git+https://github.com/pop-os/freedesktop-icons#7a61a704f6d1ec41f71cbe766e3cc484858523fa" dependencies = [ "bstr", "btoi", "memchr", - "memmap2 0.9.11", - "thiserror 2.0.20", + "memmap2 0.9.10", + "thiserror 2.0.18", "tracing", "xdg", ] [[package]] name = "cosmic-notifications-config" -version = "1.9.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-notifications#6046bb29d570161196ab98d60806f6d6489df7a6" dependencies = [ "cosmic-config", "serde", @@ -1358,10 +1467,11 @@ dependencies = [ [[package]] name = "cosmic-notifications-util" -version = "1.9.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-notifications#6046bb29d570161196ab98d60806f6d6489df7a6" dependencies = [ "fast_image_resize", - "libcosmic-yoda", + "libcosmic", "serde", "tl", "tracing", @@ -1369,21 +1479,13 @@ dependencies = [ "zbus", ] -[[package]] -name = "cosmic-osk-config" -version = "0.1.0" -dependencies = [ - "cosmic-config", - "serde", -] - [[package]] name = "cosmic-panel-button" -version = "1.9.0" +version = "1.0.2" dependencies = [ "cosmic-config", - "libcosmic-yoda", - "rustc-hash 2.1.3", + "libcosmic", + "rustc-hash 2.1.2", "serde", "tracing", "tracing-log", @@ -1392,7 +1494,8 @@ dependencies = [ [[package]] name = "cosmic-panel-config" -version = "1.9.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel#d518c7d25ef96f1a9696aa8cce008656bf66ece4" dependencies = [ "anyhow", "cosmic-config", @@ -1403,11 +1506,26 @@ dependencies = [ "xdg-shell-wrapper-config", ] +[[package]] +name = "cosmic-pipewire" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" +dependencies = [ + "intmap", + "libspa", + "libspa-sys", + "pipewire", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "cosmic-protocols" version = "0.2.0" +source = "git+https://github.com/pop-os/cosmic-protocols//?branch=main#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1418,7 +1536,8 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" -version = "1.9.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1431,7 +1550,8 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" -version = "1.9.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1442,33 +1562,21 @@ dependencies = [ ] [[package]] -name = "cosmic-settings-audio-client" -version = "1.9.0" +name = "cosmic-settings-airplane-mode-subscription" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ - "cosmic-settings-audio-core", - "dirs", - "futures-util", - "ron 0.12.2", - "serde", + "futures", + "iced_futures", + "log", + "rustix 1.1.4", "tokio", - "tokio-util", - "tracing", - "zlink", -] - -[[package]] -name = "cosmic-settings-audio-core" -version = "1.9.0" -dependencies = [ - "dirs", - "ron 0.12.2", - "serde", - "zlink", ] [[package]] name = "cosmic-settings-config" -version = "1.9.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#716da6d6af0b252e2f78aba2ad72ee19ae0241e0" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1480,14 +1588,16 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" -version = "0.1.1-yoda.1" +version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "zbus", ] [[package]] name = "cosmic-settings-daemon-subscription" -version = "1.9.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "futures", "iced_futures", @@ -1497,9 +1607,44 @@ dependencies = [ "zbus", ] +[[package]] +name = "cosmic-settings-network-manager-subscription" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" +dependencies = [ + "bitflags 2.11.0", + "cosmic-dbus-networkmanager", + "futures", + "iced_futures", + "itertools 0.14.0", + "nm-secret-agent-manager", + "secret-service", + "secure-string", + "thiserror 2.0.18", + "tokio", + "tracing", + "zbus", +] + +[[package]] +name = "cosmic-settings-sound-subscription" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" +dependencies = [ + "cosmic-pipewire", + "futures", + "intmap", + "libcosmic", + "numtoa", + "rustix 1.1.4", + "tokio", + "tracing", +] + [[package]] name = "cosmic-settings-upower-subscription" -version = "1.9.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "futures", "iced_futures", @@ -1512,17 +1657,18 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.19.0" +version = "0.18.2" +source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "fontdb", "harfrust", "linebender_resource_handle", "log", "rangemap", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "self_cell", - "skrifa 0.40.0", + "skrifa", "smol_str", "swash", "sys-locale", @@ -1530,49 +1676,48 @@ dependencies = [ "unicode-linebreak", "unicode-script", "unicode-segmentation", - "unicode-width", ] [[package]] name = "cosmic-theme" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "almost", "configparser", "cosmic-config", "csscolorparser", "dirs", - "hex_color", "palette", - "ron 0.12.2", + "ron 0.12.1", "serde", "serde_json", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] name = "cpufeatures" -version = "0.3.1" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.5.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-utils" -version = "0.8.23" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -1583,21 +1728,23 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" +source = "git+https://github.com/pop-os/glyphon.git?tag=cosmic-0.14#c49de15bce4d8254ac136d1be9911960cc85ce12" dependencies = [ "cosmic-text", "etagere", "lru", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "wgpu", ] [[package]] name = "crypto-common" -version = "0.2.2" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ - "hybrid-array", + "generic-array", + "typenum", ] [[package]] @@ -1608,16 +1755,22 @@ checksum = "42aaeae719fd78ce501d77c6cdf01f7e96f26bcd5617a4903a1c2b97e388543a" [[package]] name = "csscolorparser" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168dbdf4dced8f57fa4246ac9080598452b49d70bb2d0e46422142f113140dd8" +checksum = "199f851bd3cb5004c09474252c7f74e7c047441ed0979bf3688a7106a13da952" dependencies = [ "num-traits", - "phf", + "phf 0.13.1", "serde", "uncased", ] +[[package]] +name = "ctor-lite" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e162d0c2e2068eb736b71e5597eff0b9944e6b973cd9f37b6a288ab9bf20e300" + [[package]] name = "cursor-icon" version = "1.2.0" @@ -1642,8 +1795,8 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.119", - "synstructure 0.13.2", + "syn", + "synstructure", ] [[package]] @@ -1668,12 +1821,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.24.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.24.1", - "darling_macro 0.24.1", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -1687,7 +1840,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.119", + "syn", ] [[package]] @@ -1701,20 +1854,20 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.119", + "syn", ] [[package]] name = "darling_core" -version = "0.24.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ "ident_case", "proc-macro2", "quote", "strsim", - "syn 3.0.6", + "syn", ] [[package]] @@ -1725,7 +1878,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -1736,18 +1889,18 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "darling_macro" -version = "0.24.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.24.1", + "darling_core 0.23.0", "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -1758,15 +1911,15 @@ checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" [[package]] name = "dbus" -version = "0.9.12" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e" +checksum = "21b3aa68d7e7abee336255bd7248ea965cc393f3e70411135a6f6a4b651345d4" dependencies = [ "futures-channel", "futures-util", "libc", "libdbus-sys", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1789,46 +1942,47 @@ dependencies = [ "tokio", ] -[[package]] -name = "defmt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" -dependencies = [ - "bitflags 1.3.2", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" -dependencies = [ - "defmt-parser", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "defmt-parser" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" -dependencies = [ - "thiserror 2.0.20", -] - [[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ + "powerfmt", "serde_core", ] +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + [[package]] name = "derive_setters" version = "0.1.9" @@ -1838,29 +1992,29 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "derive_utils" -version = "0.16.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc05a5d33db20c784f873e84934ad94bb209a090987ac5f62fede2c178234f23" +checksum = "362f47930db19fe7735f527e6595e4900316b893ebf6d48ad3d31be928d57dd6" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "digest" -version = "0.11.3" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -1890,7 +2044,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1898,13 +2052,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.7" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -1919,8 +2073,9 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit", @@ -1945,6 +2100,20 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" + +[[package]] +name = "drm" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" +dependencies = [ + "bitflags 2.11.0", + "bytemuck", + "drm-ffi 0.7.1", + "drm-fourcc", + "rustix 0.38.44", +] [[package]] name = "drm" @@ -1952,22 +2121,32 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", - "drm-ffi", + "drm-ffi 0.9.1", "drm-fourcc", "libc", "rustix 0.38.44", ] +[[package]] +name = "drm-ffi" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" +dependencies = [ + "drm-sys 0.6.1", + "rustix 0.38.44", +] + [[package]] name = "drm-ffi" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51a91c9b32ac4e8105dec255e849e0d66e27d7c34d184364fb93e469db08f690" dependencies = [ - "drm-sys", - "rustix 1.1.5", + "drm-sys 0.8.1", + "rustix 1.1.4", ] [[package]] @@ -1976,6 +2155,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" +[[package]] +name = "drm-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" +dependencies = [ + "libc", + "linux-raw-sys 0.6.5", +] + [[package]] name = "drm-sys" version = "0.8.1" @@ -1994,9 +2183,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.18.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "endi" @@ -2022,7 +2211,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -2043,9 +2232,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.4.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] name = "etagere" @@ -2068,10 +2257,11 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.2" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ + "concurrent-queue", "parking", "pin-project-lite", ] @@ -2087,22 +2277,28 @@ dependencies = [ ] [[package]] -name = "fast_image_resize" -version = "6.1.0" +name = "fast-srgb8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c50201dc184ba6553da1695aac20a042efffbe2d84542cee31917c86c3ab1e" +checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" + +[[package]] +name = "fast_image_resize" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc7fe45cf92b43817ff62a3723e862b85bd1d06288f63007f7645d1d2f7a060" dependencies = [ "cfg-if", "document-features", "num-traits", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] name = "fastrand" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fdeflate" @@ -2119,14 +2315,14 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] name = "find-msvc-tools" -version = "0.1.13" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed_decimal" @@ -2141,13 +2337,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.10" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", - "miniz_oxide 0.9.1", - "zlib-rs", + "miniz_oxide", ] [[package]] @@ -2191,7 +2386,7 @@ dependencies = [ "fluent-syntax", "intl-memoizer", "intl_pluralrules", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "self_cell", "smallvec", "unic-langid", @@ -2213,7 +2408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198" dependencies = [ "memchr", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] @@ -2236,18 +2431,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.11.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "font-types" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8eb065f3251655b3c90e22e5e363f310fc5332fb3402e37bbc94752283248f6" +checksum = "2d9237c6d82152100c691fb77ea18037b402bcc7257d2c876a4ffac81bc22a1c" dependencies = [ "bytemuck", ] @@ -2269,7 +2455,7 @@ checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "slotmap", "tinyvec", "ttf-parser", @@ -2287,13 +2473,13 @@ dependencies = [ [[package]] name = "foreign-types-macros" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -2313,15 +2499,15 @@ dependencies = [ [[package]] name = "freedesktop-desktop-entry" -version = "0.8.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cfa09933e03f1ced380ad639822d65cb59a1914217da6c72aa8db3563e94214" +checksum = "28273c5c6b97a5f07724f6652f064c0c7f637f9aa5e7c09c83bc3bc4ad4ea245" dependencies = [ "bstr", "gettext-rs", "log", "memchr", - "thiserror 2.0.20", + "thiserror 2.0.18", "unicase", "xdg", ] @@ -2332,8 +2518,8 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6d3a3635983a889f065aa9ce760384713f23a9b4a04f696f86c39a5d7a6a5a" dependencies = [ - "indexmap 2.14.2", - "nom", + "indexmap 2.14.0", + "nom 8.0.0", ] [[package]] @@ -2347,9 +2533,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -2362,9 +2548,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -2372,15 +2558,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -2389,9 +2575,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-lite" @@ -2408,38 +2594,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" - -[[package]] -name = "futures-timer" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.34" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -2452,6 +2632,26 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.4", + "windows-link 0.2.1", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -2477,20 +2677,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "wasip2", + "wasip3", ] [[package]] name = "gettext-rs" -version = "0.8.0" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df5e3fa8c077b15fdfa8ce130e2bc73d663b8aaa6d51b71421b8659980b1d80" +checksum = "5d5857dc1b7f0fee86961de833f434e29494d72af102ce5355738c0664222bdf" dependencies = [ "gettext-sys", "locale_config", @@ -2498,9 +2700,9 @@ dependencies = [ [[package]] name = "gettext-sys" -version = "0.27.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa7e4460b196107cc1bb2629488e8b6dbb7f34f6683ea6753c4ac22f590785" +checksum = "4ea859ab0dd7e70ff823032b3e077d03d39c965d68c6c10775add60e999d8ee9" dependencies = [ "cc", "temp-dir", @@ -2533,6 +2735,12 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "glow" version = "0.16.0" @@ -2555,17 +2763,34 @@ dependencies = [ ] [[package]] -name = "gpu-allocator" -version = "0.28.0" +name = "gpu-alloc" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.11.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" dependencies = [ - "ash", - "hashbrown 0.16.1", "log", "presser", - "thiserror 2.0.20", - "windows 0.62.2", + "thiserror 1.0.69", + "windows 0.58.0", ] [[package]] @@ -2574,7 +2799,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2585,14 +2810,14 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", ] [[package]] name = "grid" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" +checksum = "f9e2d4c0a8296178d8802098410ca05d86b17a10bb5ab559b3fb404c1f948220" [[package]] name = "guillotiere" @@ -2622,10 +2847,10 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "core_maths", - "read-fonts 0.37.0", + "read-fonts", "smallvec", ] @@ -2650,16 +2875,14 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.2.0", ] [[package]] name = "hashbrown" -version = "0.17.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" [[package]] name = "heck" @@ -2681,9 +2904,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hermit-abi" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -2691,17 +2914,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex_color" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37f101bf4c633f7ca2e4b5e136050314503dd198e78e325ea602c327c484ef0" -dependencies = [ - "arrayvec", - "rand 0.8.8", - "serde", -] - [[package]] name = "hexf-parse" version = "0.2.1" @@ -2709,12 +2921,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] -name = "hybrid-array" -version = "0.4.15" +name = "hkdf" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "typenum", + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", ] [[package]] @@ -2754,20 +2975,20 @@ dependencies = [ [[package]] name = "i18n-embed-fl" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602e6bd30c3db2749e13e38b363a3d98d9d41de1d8de7a79c31bb69e45b47cda" +checksum = "e598ed73b67db92f61e04672e599eef2991a262a40e1666735b8a86d2e7e9f30" dependencies = [ "find-crate", "fluent", "fluent-syntax", "i18n-config", "i18n-embed", - "proc-macro-error3", + "proc-macro-error2", "proc-macro2", "quote", "strsim", - "syn 2.0.119", + "syn", "unic-langid", ] @@ -2781,7 +3002,7 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -2811,8 +3032,8 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "build_helpers", "dnd", "iced_accessibility", "iced_core", @@ -2825,13 +3046,14 @@ dependencies = [ "iced_winit", "image", "mime 0.1.0", - "thiserror 2.0.20", + "thiserror 2.0.18", "window_clipboard", ] [[package]] name = "iced_accessibility" version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "accesskit", "accesskit_winit", @@ -2840,9 +3062,9 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "bitflags 2.13.2", - "build_helpers", + "bitflags 2.11.0", "bytes", "cosmic-client-toolkit", "dnd", @@ -2853,11 +3075,10 @@ dependencies = [ "num-traits", "palette", "raw-window-handle", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "serde", "smol_str", - "thiserror 2.0.20", - "unicode-segmentation", + "thiserror 2.0.18", "web-time", "window_clipboard", ] @@ -2865,6 +3086,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_core", "iced_futures", @@ -2874,11 +3096,12 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "futures", "iced_core", "log", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "tokio", "wasm-bindgen-futures", "wasmtimer", @@ -2887,8 +3110,9 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "cosmic-text", "half", @@ -2899,14 +3123,15 @@ dependencies = [ "log", "lyon_path", "raw-window-handle", - "rustc-hash 2.1.3", - "thiserror 2.0.20", + "rustc-hash 2.1.2", + "thiserror 2.0.18", "unicode-segmentation", ] [[package]] name = "iced_program" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_runtime", @@ -2915,32 +3140,34 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_tiny_skia", "iced_wgpu", "log", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] name = "iced_runtime" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "build_helpers", "bytes", "cosmic-client-toolkit", "dnd", "iced_core", "iced_futures", "raw-window-handle", - "thiserror 2.0.20", + "thiserror 2.0.18", "window_clipboard", ] [[package]] name = "iced_tiny_skia" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bytemuck", "cosmic-text", @@ -2949,17 +3176,18 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "softbuffer", - "tiny-skia 0.11.4", + "tiny-skia", ] [[package]] name = "iced_wgpu" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "bitflags 2.13.2", - "build_helpers", + "as-raw-xcb-connection", + "bitflags 2.11.0", "bytemuck", "cosmic-client-toolkit", "cryoglyph", @@ -2972,21 +3200,23 @@ dependencies = [ "lyon", "raw-window-handle", "resvg", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "rustix 0.38.44", - "thiserror 2.0.20", + "thiserror 2.0.18", + "tiny-xlib", "wayland-backend", "wayland-client", "wayland-protocols", "wayland-sys", "wgpu", + "x11rb", ] [[package]] name = "iced_widget" version = "0.14.2" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "build_helpers", "cosmic-client-toolkit", "dnd", "iced_renderer", @@ -2994,8 +3224,8 @@ dependencies = [ "log", "num-traits", "ouroboros", - "rustc-hash 2.1.3", - "thiserror 2.0.20", + "rustc-hash 2.1.2", + "thiserror 2.0.18", "unicode-segmentation", "window_clipboard", ] @@ -3003,8 +3233,8 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "build_helpers", "cosmic-client-toolkit", "cursor-icon", "dnd", @@ -3015,9 +3245,9 @@ dependencies = [ "iced_runtime", "log", "raw-window-handle", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "rustix 0.38.44", - "thiserror 2.0.20", + "thiserror 2.0.18", "wasm-bindgen-futures", "wayland-backend", "wayland-client", @@ -3034,9 +3264,9 @@ dependencies = [ [[package]] name = "icu" -version = "2.3.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4867dd3a39b9d48632416cc7fc3dfa1913d89fd36cc02fe7bfc1dddc6fda3cde" +checksum = "00380f83691e089bcfa4aeb03a2d96a910b1c9ea406d6f822fc19dfb8b58d1ec" dependencies = [ "icu_calendar", "icu_casemap", @@ -3058,15 +3288,15 @@ dependencies = [ [[package]] name = "icu_calendar" -version = "2.3.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58655df2f728e46e4eee80bddebefacf52ec3e77cdb925014b47c5a5905eb55c" +checksum = "a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45" dependencies = [ "calendrical_calculations", "displaydoc", "icu_calendar_data", + "icu_locale", "icu_locale_core", - "icu_locale_fallback", "icu_provider", "ixdtf", "serde", @@ -3076,15 +3306,15 @@ dependencies = [ [[package]] name = "icu_calendar_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc00caaa3fb3201ff7a18aa458e8c3ab042b9da154cfdf948bdde3936c31c36e" +checksum = "118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d" [[package]] name = "icu_casemap" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2edfd120d8445de853cf53a1abec916f638f933a70a6f4bf8f7e2d7b7f884e9" +checksum = "070f98b5b82798fcb93654bf96ed9f40064fc44c86f51a09ea711092cd5cc5be" dependencies = [ "icu_casemap_data", "icu_collections", @@ -3098,20 +3328,20 @@ dependencies = [ [[package]] name = "icu_casemap_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "059fcda0fc8d33effc6633a8cf0d8a3c17caf7d7c91918fba9918744f501e4e8" +checksum = "846b0857ca091204be3c874bc93daaf89d4777e8d2d20b0d3ffe8f671d98014b" [[package]] name = "icu_collator" -version = "2.3.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08984ed58ac439ebf3e13d2cf26b0c46a60afcd21721c1d14087c0b240344dda" +checksum = "b521b92a2666061ddda902769d8a4cf730b5c9529a845cc1b69770b12a6c9a71" dependencies = [ "icu_collator_data", "icu_collections", + "icu_locale", "icu_locale_core", - "icu_locale_fallback", "icu_normalizer", "icu_properties", "icu_provider", @@ -3123,15 +3353,15 @@ dependencies = [ [[package]] name = "icu_collator_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d7e54efdddeb1208c08dd5d32b53a879ac00d2d3d051b2255fd26821d16368" +checksum = "038ed8e5817f2059c2f3efb0945ba78d060d3d25e8f1a1bea5139f821a21a2f0" [[package]] name = "icu_collections" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", @@ -3144,17 +3374,17 @@ dependencies = [ [[package]] name = "icu_datetime" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44df99c4c5297b05653d1a1629f13bdc9fd4044acfbbaf30b15194a1eed4cd6" +checksum = "989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72" dependencies = [ "displaydoc", "fixed_decimal", "icu_calendar", "icu_datetime_data", "icu_decimal", + "icu_locale", "icu_locale_core", - "icu_locale_fallback", "icu_pattern", "icu_plurals", "icu_provider", @@ -3167,21 +3397,21 @@ dependencies = [ [[package]] name = "icu_datetime_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb5555f6e4b42233f58564351ce16d73e9e6ebfce6bdcf29875d0cfc554d6a8" +checksum = "40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b" [[package]] name = "icu_decimal" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eb8f655bba2d0c0459e43a5b0e6cd3cd388109898fb3d85d048165e8b0abd08" +checksum = "288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4" dependencies = [ "displaydoc", "fixed_decimal", "icu_decimal_data", + "icu_locale", "icu_locale_core", - "icu_locale_fallback", "icu_pattern", "icu_plurals", "icu_provider", @@ -3192,15 +3422,15 @@ dependencies = [ [[package]] name = "icu_decimal_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c887fc7d4c297cf3f9436864af9e3dba7f8be9415a6c2a7f392f3b1636298c" +checksum = "6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22" [[package]] name = "icu_experimental" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c09609ad18e249b97a0afa20e19502c4d11ab039e6e35f5ecf48bebd4eedd7e" +checksum = "0a881116e620fd635f564fd9cb9bc36c256b9da2221df8b3f55643d8ef32140f" dependencies = [ "displaydoc", "either", @@ -3212,7 +3442,6 @@ dependencies = [ "icu_list", "icu_locale", "icu_locale_core", - "icu_locale_fallback", "icu_normalizer", "icu_pattern", "icu_plurals", @@ -3232,18 +3461,18 @@ dependencies = [ [[package]] name = "icu_experimental_data" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377481a8935d6774f410424d79a6dc8a09d9bd8def9560cff17abe755a246280" +checksum = "f72090d4f08a2bc94565cb02de6d5b87939424e462d9927d73a34f6f8e5d1232" [[package]] name = "icu_list" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5c625125085fac4bf9ad111888a90c6ab9dc7bcaec392ca79cab417f46e3fb" +checksum = "aeeaf517689324395bed4767f7c65504f5455942ed4c14ee54c2087ca00b816e" dependencies = [ "icu_list_data", - "icu_locale_fallback", + "icu_locale", "icu_provider", "regex-automata", "serde", @@ -3253,30 +3482,30 @@ dependencies = [ [[package]] name = "icu_list_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffef91ee351bd195a803115615a034dfb9f02bb48850980548c31cb78568a91" +checksum = "ed62dbf114db9a4163481ed071509c4cd52cbcef9cb85979eba08a95549d73f3" [[package]] name = "icu_locale" -version = "2.3.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "785f595c61ef57169a467eeed7b4b6936a66f6cacbb116a96ee86da983251bf4" +checksum = "d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26" dependencies = [ "icu_collections", "icu_locale_core", "icu_locale_data", - "icu_locale_fallback", "icu_provider", + "potential_utf", "tinystr", "zerovec", ] [[package]] name = "icu_locale_core" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -3288,35 +3517,15 @@ dependencies = [ [[package]] name = "icu_locale_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37d91460e362a5cf58907cd7ce871411775ee6294e49a5cc8e6cec16dfa75ea" - -[[package]] -name = "icu_locale_fallback" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "251af8e57c9400e3eb58242fe5b8b1152b2a64fdf4cf632f923c38ccee6f2fa9" -dependencies = [ - "icu_locale_core", - "icu_locale_fallback_data", - "icu_provider", - "potential_utf", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locale_fallback_data" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decf2a22ec8fa68f1a0c1129a3f8583f8f8bc24e8b9ccbe98ead99f62a4dc3a8" +checksum = "d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993" [[package]] name = "icu_normalizer" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -3331,15 +3540,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_pattern" -version = "0.5.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3db611446bd92c246b03e4aa0bafa71ddb194af431ddbb42b9d70e4bfce1a0" +checksum = "1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb" dependencies = [ "displaydoc", "either", @@ -3351,12 +3560,12 @@ dependencies = [ [[package]] name = "icu_plurals" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e475e6766ef87b1d3c1f97be6363995b0bfaeddbc789671615df598a97ff0593" +checksum = "2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103" dependencies = [ "fixed_decimal", - "icu_locale_fallback", + "icu_locale", "icu_plurals_data", "icu_provider", "zerovec", @@ -3364,17 +3573,16 @@ dependencies = [ [[package]] name = "icu_plurals_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1251aa39a95e1333888e499b1263e1c196447a28948acf5bdabd82c046f153bf" +checksum = "8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d" [[package]] name = "icu_properties" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -3386,15 +3594,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.3.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -3409,32 +3617,31 @@ dependencies = [ [[package]] name = "icu_segmenter" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d07aafccd67af15d02512a6adf5896fbc5ed00f2e99b471d2efa14016db3db" +checksum = "5c0794db0b1a86193ac9c48768d0e6c52c54448e0870ad87907d456ee0dac964" dependencies = [ "core_maths", "icu_collections", - "icu_locale_fallback", + "icu_locale", "icu_provider", "icu_segmenter_data", "potential_utf", - "smallvec", "utf8_iter", "zerovec", ] [[package]] name = "icu_segmenter_data" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae293c039020f9ec10710af98d29ce6aa2051486638b49c9a6409f3b4a9e98ad" +checksum = "e4a2c462a4d927d512f5f882a033ddd62f33a05bb9f230d98f736ac3dc85938f" [[package]] name = "icu_time" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af37e1c3b9f3ab564b619fdf4b22de169f6381eb0f7048e3ca454290c438126b" +checksum = "ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a" dependencies = [ "calendrical_calculations", "displaydoc", @@ -3450,9 +3657,15 @@ dependencies = [ [[package]] name = "icu_time_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2f8aeca682d874a5247084aa4fb7d1cef9ba45d889c21209a8818dcaaa0ec9" + +[[package]] +name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005ff86fa5851a77fc0a977b72d717f777bd9230415a247219d7898aefb1517a" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "ident_case" @@ -3473,9 +3686,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -3492,19 +3705,10 @@ dependencies = [ "moxcms", "num-traits", "png 0.18.1", - "zune-core 0.5.3", + "zune-core 0.5.1", "zune-jpeg 0.5.15", ] -[[package]] -name = "image-extras" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d02eb2c9ccbbab470538fce34c7bc3be7b4e59268e65a3171367b296cdb842" -dependencies = [ - "image", -] - [[package]] name = "image-webp" version = "0.2.4" @@ -3534,43 +3738,53 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.2" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.1", + "hashbrown 0.17.0", "serde", "serde_core", ] [[package]] name = "inotify" -version = "0.11.5" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00ea907cab49550b7da656f80ebb97be1b997d931fbcd28d39734e17ce592" +checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "inotify-sys", "libc", ] [[package]] name = "inotify-sys" -version = "0.1.8" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" dependencies = [ "libc", ] [[package]] -name = "input" -version = "0.10.0" +name = "inout" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9793345a65d71317763a33066b5d8351f8760dde8d4930fe9e39b5f14a7959d" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "bitflags 2.13.2", + "block-padding", + "generic-array", +] + +[[package]] +name = "input" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbdc09524a91f9cacd26f16734ff63d7dc650daffadd2b6f84d17a285bd875a9" +dependencies = [ + "bitflags 2.11.0", "input-sys", "libc", "log", @@ -3619,6 +3833,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -3627,54 +3859,41 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "ixdtf" -version = "0.6.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3667095d64c3ecffc96463a21157b04bf3e252f6e8d5750b20c02e33c194e3" +checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.37" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" dependencies = [ - "defmt", - "jiff-core", "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", - "windows-link 0.2.1", -] - -[[package]] -name = "jiff-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" -dependencies = [ - "defmt", - "log", + "windows-sys 0.61.2", ] [[package]] name = "jiff-static" -version = "0.2.37" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" dependencies = [ - "jiff-core", "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "jiff-tzdb" -version = "0.1.8" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" +checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" [[package]] name = "jiff-tzdb-platform" @@ -3697,7 +3916,7 @@ dependencies = [ "jni-sys 0.4.1", "log", "simd_cesu8", - "thiserror 2.0.20", + "thiserror 2.0.18", "walkdir", "windows-link 0.2.1", ] @@ -3712,7 +3931,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn 2.0.119", + "syn", ] [[package]] @@ -3740,27 +3959,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "jobserver" -version = "0.1.35" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.4.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.105" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ "cfg-if", "futures-util", + "once_cell", "wasm-bindgen", ] @@ -3779,7 +3999,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "serde", ] @@ -3811,9 +4031,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.2.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d763e5b24120b4ddf50de6c92308156765aabfbbccebf401da7cff2d70a41ea" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -3821,11 +4041,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.1.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" dependencies = [ - "bitflags 2.13.2", + "bitflags 1.3.2", "libc", ] @@ -3857,19 +4077,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "libc" -version = "0.2.189" +name = "leb128fmt" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] -name = "libcosmic-yoda" -version = "0.1.0-yoda.2" +name = "libc" +version = "0.2.184" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" + +[[package]] +name = "libcosmic" +version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", - "build_helpers", "cosmic-client-toolkit", "cosmic-config", "cosmic-freedesktop-icons", @@ -3879,7 +4105,6 @@ dependencies = [ "cosmic-theme", "css-color", "derive_setters", - "enumflags2", "float-cmp 0.10.0", "freedesktop-desktop-entry", "futures", @@ -3895,23 +4120,21 @@ dependencies = [ "iced_widget", "iced_winit", "image", - "image-extras", "jiff", "libc", "log", "mime 0.3.17", "palette", - "phf", + "phf 0.13.1", "rfd", - "ron 0.12.2", - "roxmltree", + "ron 0.12.1", "rust-embed", - "rustix 1.1.5", + "rustix 1.1.4", "serde", - "shlex 1.3.0", + "shlex", "slotmap", "taffy", - "thiserror 2.0.20", + "thiserror 2.0.18", "tokio", "tracing", "unicode-segmentation", @@ -3946,14 +4169,42 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.25" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "libc", "plain", - "redox_syscall 0.9.4", + "redox_syscall 0.7.4", +] + +[[package]] +name = "libspa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4" +dependencies = [ + "bitflags 2.11.0", + "cc", + "convert_case", + "cookie-factory", + "libc", + "libspa-sys", + "nix 0.30.1", + "nom 8.0.0", + "system-deps", +] + +[[package]] +name = "libspa-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901049455d2eb6decf9058235d745237952f4804bc584c5fcb41412e6adcc6e0" +dependencies = [ + "bindgen", + "cc", + "system-deps", ] [[package]] @@ -3968,9 +4219,9 @@ dependencies = [ [[package]] name = "lilt" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "337d4c256f7d9f2dbd633891d48ace853efa5b1554122d9220b172ad9c03c3a9" +checksum = "f67562e5eff6b20553fa9be1c503356768420994e28f67e3eafe6f41910e57ad" dependencies = [ "web-time", ] @@ -3987,6 +4238,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" + [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -4001,9 +4258,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "litrs" @@ -4035,9 +4292,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.34" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "logind-zbus" @@ -4051,9 +4308,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.4" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" [[package]] name = "lyon" @@ -4067,9 +4324,9 @@ dependencies = [ [[package]] name = "lyon_algorithms" -version = "1.0.21" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdfa8785f95e57914ddb35e3b59994aeba6f5e79e9cfd03da1c269f010f36009" +checksum = "9815fac08e6fd96733a11dce4f9d15a3f338e96a2e2311ee21e1b738efc2bc0f" dependencies = [ "lyon_path", "num-traits", @@ -4098,9 +4355,9 @@ dependencies = [ [[package]] name = "lyon_tessellation" -version = "1.0.22" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b8dcf906637ecef61b3c0740c7a4e7f27caeb31257cfac0cc579ce15be6005" +checksum = "8e43b7e44161571868f5c931d12583592c223c5583eef86b08aa02b7048a3552" dependencies = [ "float_next_after", "lyon_path", @@ -4133,9 +4390,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.3" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -4148,9 +4405,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.11" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -4166,11 +4423,11 @@ dependencies = [ [[package]] name = "metal" -version = "0.33.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" +checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -4182,6 +4439,7 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "smithay-clipboard", ] @@ -4193,14 +4451,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] -name = "mime_guess" -version = "2.0.5" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime 0.3.17", - "unicase", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" @@ -4212,21 +4466,11 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "miniz_oxide" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" -dependencies = [ - "adler2", - "simd-adler32", -] - [[package]] name = "mio" -version = "1.2.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", @@ -4247,11 +4491,12 @@ dependencies = [ [[package]] name = "mpris2-zbus" version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "futures-util", "jiff", "serde", - "thiserror 2.0.20", + "thiserror 2.0.18", "zbus", "zvariant", ] @@ -4264,27 +4509,27 @@ checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af" [[package]] name = "naga" -version = "28.0.0" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" +checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.13.2", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "codespan-reporting", "half", "hashbrown 0.16.1", "hexf-parse", - "indexmap 2.14.2", + "indexmap 2.14.0", "libm", "log", "num-traits", "once_cell", "rustc-hash 1.1.0", "spirv", - "thiserror 2.0.20", + "thiserror 2.0.18", "unicode-ident", ] @@ -4294,7 +4539,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "jni-sys 0.3.1", "log", "ndk-sys", @@ -4324,30 +4569,40 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "libc", ] [[package]] -name = "nmrs" -version = "3.5.3" +name = "nix" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ad7c7fb5d3552a6b08801a6fe858ec4e3af49be51b53cba51fa6615155f3f3" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nm-secret-agent-manager" +version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ - "async-trait", - "base64 0.22.1", - "bitflags 2.13.2", - "futures", - "futures-timer", - "log", - "serde", - "thiserror 2.0.20", - "tokio", - "uuid", "zbus", - "zvariant", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", ] [[package]] @@ -4365,7 +4620,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "fsevent-sys", "inotify", "kqueue", @@ -4383,7 +4638,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", ] [[package]] @@ -4396,20 +4651,43 @@ dependencies = [ ] [[package]] -name = "num-bigint" -version = "0.4.8" +name = "num" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", ] [[package]] -name = "num-conv" -version = "0.2.2" +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -4419,18 +4697,29 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "num-integer" -version = "0.1.47" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -4471,9 +4760,15 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] +[[package]] +name = "numtoa" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e4d8a81ede501fad07191e746a299f4d79f6dcd053bab1b97af4ff5a90099f2" + [[package]] name = "objc" version = "0.2.7" @@ -4525,7 +4820,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -4541,7 +4836,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -4554,7 +4849,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4566,7 +4861,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "objc2 0.6.4", @@ -4578,7 +4873,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "libc", "objc2-core-foundation", ] @@ -4601,7 +4896,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "objc2-core-foundation", "objc2-core-graphics", ] @@ -4618,7 +4913,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -4630,7 +4925,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -4642,7 +4937,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4654,7 +4949,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4667,7 +4962,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "objc2 0.6.4", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -4696,9 +4991,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.55" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +checksum = "59aed3b33578edcfa1bc96a321d590d31832b6ad55a26f0313362ce687e9abd6" dependencies = [ "libc", "libredox", @@ -4706,9 +5001,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.5.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" dependencies = [ "num-traits", ] @@ -4744,7 +5039,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -4758,35 +5053,29 @@ dependencies = [ [[package]] name = "palette" -version = "0.7.7" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddeed8580d347d2abf3dcf06a5f0b3dc020258338526b277847cd4248a70fc64" +checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" dependencies = [ "approx", + "fast-srgb8", "palette_derive", - "palette_math", - "phf", + "phf 0.11.3", "serde", ] [[package]] name = "palette_derive" -version = "0.7.7" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88537020289b719d81be994ccf1bbf4990f477e2f69ee52fe3e45f43a02e56be" +checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] -[[package]] -name = "palette_math" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6eb142958d64335fb0e345c5b9ead2ecd6fc438c307e9d7d3c4fd428dbaf12" - [[package]] name = "parking" version = "2.2.1" @@ -4828,17 +5117,37 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + [[package]] name = "phf" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_macros", - "phf_shared", + "phf_macros 0.13.1", + "phf_shared 0.13.1", "serde", ] +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + [[package]] name = "phf_generator" version = "0.13.1" @@ -4846,7 +5155,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared", + "phf_shared 0.13.1", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4855,14 +5177,23 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", - "syn 2.0.119", + "syn", "uncased", ] +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + [[package]] name = "phf_shared" version = "0.13.1" @@ -4881,22 +5212,22 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.13" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.13" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -4923,10 +5254,38 @@ dependencies = [ ] [[package]] -name = "pkg-config" -version = "0.3.34" +name = "pipewire" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" +checksum = "9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "libc", + "libspa", + "libspa-sys", + "nix 0.30.1", + "once_cell", + "pipewire-sys", + "thiserror 2.0.18", +] + +[[package]] +name = "pipewire-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb028afee0d6ca17020b090e3b8fa2d7de23305aef975c7e5192a5050246ea36" +dependencies = [ + "bindgen", + "libspa-sys", + "system-deps", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plain" @@ -4944,7 +5303,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -4953,11 +5312,11 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -4968,9 +5327,9 @@ checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.5.3", + "hermit-abi 0.5.2", "pin-project-lite", - "rustix 1.1.5", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -4982,24 +5341,24 @@ checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" [[package]] name = "portable-atomic" -version = "1.15.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.8" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "serde_core", "writeable", @@ -5027,6 +5386,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -5037,32 +5406,32 @@ dependencies = [ ] [[package]] -name = "proc-macro-error-attr3" -version = "3.1.1" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e564d14133360e1ae169ffde5da25881b5fa47261665b8e5713c212c27799da" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ "proc-macro2", "quote", ] [[package]] -name = "proc-macro-error3" -version = "3.1.1" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0d4471b3436c22106b21913b1dda531558918ae9b7ec55d58aa84b43552233" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ - "proc-macro-error-attr3", + "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.107" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -5075,22 +5444,43 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", "version_check", "yansi", ] [[package]] -name = "profiling" -version = "1.0.18" +name = "procfs" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" +dependencies = [ + "bitflags 2.11.0", + "procfs-core", + "rustix 1.1.4", +] + +[[package]] +name = "procfs-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" +dependencies = [ + "bitflags 2.11.0", + "hex", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" [[package]] name = "pxfm" -version = "0.1.30" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" +checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" [[package]] name = "quick-error" @@ -5100,18 +5490,28 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.41.0" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quick-xml" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.47" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -5130,35 +5530,23 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.8" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha 0.3.1", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", + "rand_chacha", "rand_core 0.9.5", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -5174,9 +5562,6 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] [[package]] name = "rand_core" @@ -5195,9 +5580,9 @@ checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" [[package]] name = "rangemap" -version = "1.8.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a611d15b50743feb4c76b7d03edcb0e64f399c26961e4efe6975bc398be6aa3d" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" [[package]] name = "raw-window-handle" @@ -5213,28 +5598,7 @@ checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" dependencies = [ "bytemuck", "core_maths", - "font-types 0.11.3", -] - -[[package]] -name = "read-fonts" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" -dependencies = [ - "bytemuck", - "font-types 0.12.5", - "once_cell", -] - -[[package]] -name = "redox_event" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15" -dependencies = [ - "bitflags 2.13.2", - "libredox", + "font-types", ] [[package]] @@ -5243,53 +5607,54 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", ] [[package]] name = "redox_syscall" -version = "0.9.4" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "737970939a87c6fa31e7acad13307bccbb017a073b695b6089a2c484f929e20e" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", ] [[package]] name = "redox_users" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ + "getrandom 0.2.17", "libredox", - "thiserror 2.0.20", + "thiserror 2.0.18", ] [[package]] name = "ref-cast" -version = "1.0.27" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.27" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "regex" -version = "1.13.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -5299,9 +5664,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.18" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -5310,9 +5675,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.11" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "renderdoc-sys" @@ -5332,7 +5697,7 @@ dependencies = [ "pico-args", "rgb", "svgtypes", - "tiny-skia 0.11.4", + "tiny-skia", "usvg", "zune-jpeg 0.4.21", ] @@ -5376,8 +5741,8 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ - "base64 0.22.1", - "bitflags 2.13.2", + "base64", + "bitflags 2.11.0", "serde", "serde_derive", "unicode-ident", @@ -5385,11 +5750,11 @@ dependencies = [ [[package]] name = "ron" -version = "0.12.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "once_cell", "serde", "serde_derive", @@ -5405,9 +5770,9 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" [[package]] name = "rust-embed" -version = "8.12.0" +version = "8.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e7760e252aaba7b09f4be00e36476cf585bdb68a53552ac954cdf504ab4bc9" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -5416,23 +5781,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.12.0" +version = "8.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" dependencies = [ - "mime_guess", "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.119", + "syn", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.12.0" +version = "8.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ "sha2", "walkdir", @@ -5446,9 +5810,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.3" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -5465,7 +5829,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -5474,11 +5838,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.5" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -5487,9 +5851,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.23" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustybuzz" @@ -5497,7 +5861,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "core_maths", "log", @@ -5509,12 +5873,6 @@ dependencies = [ "unicode-script", ] -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - [[package]] name = "same-file" version = "1.0.6" @@ -5538,9 +5896,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ "dyn-clone", "ref-cast", @@ -5562,15 +5920,34 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2a4360b9abcdcee43809e6fc11d6d61ca5d25734026a8fc46c2883eea3f13f" +checksum = "1dd3accc0f3f4bbaf2c9e1957a030dc582028130c67660d44c0a0345a22ca69b" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "smithay-client-toolkit", - "tiny-skia 0.12.0", + "tiny-skia", +] + +[[package]] +name = "secret-service" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a62d7f86047af0077255a29494136b9aaaf697c76ff70b8e49cded4e2623c14" +dependencies = [ + "aes", + "cbc", + "futures-util", + "generic-array", + "getrandom 0.2.17", + "hkdf", + "num", + "once_cell", + "serde", + "sha2", + "zbus", ] [[package]] @@ -5585,9 +5962,9 @@ dependencies = [ [[package]] name = "self_cell" -version = "1.3.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" +checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" [[package]] name = "semver" @@ -5597,9 +5974,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.229" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -5619,31 +5996,31 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.229" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.229" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "serde_json" -version = "1.0.151" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.14.2", + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -5653,30 +6030,37 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.21" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", ] [[package]] name = "serde_with" -version = "3.23.0" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ - "base64 0.23.1", - "bs58", + "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.14.2", - "jiff", + "indexmap 2.14.0", "schemars 0.9.0", - "schemars 1.2.2", + "schemars 1.2.1", "serde_core", "serde_json", "serde_with_macros", @@ -5685,27 +6069,21 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.23.0" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d607aa01a3cb0ad757d6fd216136910db3c97b102fe686585689615a02dbcdc" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ - "darling 0.24.1", + "darling 0.23.0", "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - [[package]] name = "sha2" -version = "0.11.0" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -5727,12 +6105,6 @@ 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" @@ -5745,15 +6117,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.10" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_cesu8" -version = "1.2.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" dependencies = [ "rustc_version", "simdutf8", @@ -5776,9 +6148,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "skrifa" @@ -5787,17 +6159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" dependencies = [ "bytemuck", - "read-fonts 0.37.0", -] - -[[package]] -name = "skrifa" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" -dependencies = [ - "bytemuck", - "read-fonts 0.41.0", + "read-fonts", ] [[package]] @@ -5817,9 +6179,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.16.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay-client-toolkit" @@ -5827,17 +6189,17 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "pkg-config", - "rustix 1.1.5", - "thiserror 2.0.20", + "rustix 1.1.4", + "thiserror 2.0.18", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -5854,6 +6216,7 @@ dependencies = [ [[package]] name = "smithay-clipboard" version = "0.8.0" +source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b" dependencies = [ "libc", "raw-window-handle", @@ -5873,9 +6236,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", "windows-sys 0.61.2", @@ -5884,26 +6247,31 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" +source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb" dependencies = [ + "as-raw-xcb-connection", "bytemuck", "cfg_aliases", "cocoa", "core-graphics", + "drm 0.11.1", "fastrand", "foreign-types", "js-sys", - "libredox", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "objc", "raw-window-handle", + "redox_syscall 0.5.18", "rustix 0.38.44", + "tiny-xlib", "wasm-bindgen", "wayland-backend", "wayland-client", "wayland-sys", "web-sys", "windows-sys 0.52.0", + "x11rb", ] [[package]] @@ -5912,7 +6280,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", ] [[package]] @@ -5961,9 +6329,15 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.119", + "syn", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "svg_fmt" version = "0.4.5" @@ -5982,11 +6356,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.10" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e" +checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64" dependencies = [ - "skrifa 0.44.0", + "skrifa", "yazi", "zeno", ] @@ -5994,26 +6368,16 @@ dependencies = [ [[package]] name = "switcheroo-control" version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "zbus", ] [[package]] name = "syn" -version = "2.0.119" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -6028,18 +6392,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", -] - -[[package]] -name = "synstructure" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.6", + "syn", ] [[package]] @@ -6051,6 +6404,19 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "7.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 1.1.2+spec-1.1.0", + "version-compare", +] + [[package]] name = "taffy" version = "0.9.2" @@ -6063,6 +6429,12 @@ dependencies = [ "slotmap", ] +[[package]] +name = "target-lexicon" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" + [[package]] name = "temp-dir" version = "0.1.16" @@ -6076,9 +6448,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.3", + "getrandom 0.4.2", "once_cell", - "rustix 1.1.5", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -6102,11 +6474,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.20" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.20", + "thiserror-impl 2.0.18", ] [[package]] @@ -6117,36 +6489,37 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "thiserror-impl" -version = "2.0.20" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "thread_local" -version = "1.1.10" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", ] [[package]] name = "time" -version = "0.3.55" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde_core", @@ -6156,15 +6529,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.32" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -6173,6 +6546,7 @@ dependencies = [ [[package]] name = "timedate-zbus" version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "zbus", ] @@ -6189,21 +6563,7 @@ dependencies = [ "cfg-if", "log", "png 0.17.16", - "tiny-skia-path 0.11.4", -] - -[[package]] -name = "tiny-skia" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47ffee5eaaf5527f630fb0e356b90ebdec84d5d18d937c5e440350f88c5a91ea" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "tiny-skia-path 0.12.0", + "tiny-skia-path", ] [[package]] @@ -6218,21 +6578,23 @@ dependencies = [ ] [[package]] -name = "tiny-skia-path" -version = "0.12.0" +name = "tiny-xlib" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca365c3faccca67d06593c5980fa6c57687de727a03131735bb85f01fdeeb9" +checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" dependencies = [ - "arrayref", - "bytemuck", - "strict-num", + "as-raw-xcb-connection", + "ctor-lite", + "libloading", + "pkg-config", + "tracing", ] [[package]] name = "tinystr" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "serde_core", @@ -6241,9 +6603,18 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.13.3" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tl" @@ -6253,9 +6624,9 @@ checksum = "b130bd8a58c163224b44e217b4239ca7b927d82bf6cc2fea1fc561d15056e3f7" [[package]] name = "tokio" -version = "1.53.1" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -6271,39 +6642,24 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", + "syn", ] [[package]] name = "tokio-stream" -version = "0.1.19" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-util" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "libc", - "pin-project-lite", - "tokio", ] [[package]] @@ -6315,6 +6671,21 @@ dependencies = [ "serde", ] +[[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 2.14.0", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow 1.0.1", +] + [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -6326,25 +6697,31 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.15+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap 2.14.2", + "indexmap 2.14.0", "toml_datetime", "toml_parser", - "winnow", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.1.3+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.1", ] +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -6365,7 +6742,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -6422,7 +6799,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" dependencies = [ - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", ] [[package]] @@ -6433,9 +6810,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "udev" @@ -6514,9 +6891,9 @@ checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" [[package]] name = "unicode-ident" -version = "1.0.26" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-linebreak" @@ -6538,9 +6915,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.13.3" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-vo" @@ -6554,10 +6931,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "upower_dbus" version = "0.3.2" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "serde", "serde_repr", @@ -6589,7 +6972,7 @@ version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" dependencies = [ - "base64 0.22.1", + "base64", "data-url", "flate2", "fontdb", @@ -6603,7 +6986,7 @@ dependencies = [ "siphasher", "strict-num", "svgtypes", - "tiny-skia-path 0.11.4", + "tiny-skia-path", "unicode-bidi", "unicode-script", "unicode-vo", @@ -6624,14 +7007,13 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.26.1" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom 0.4.3", + "getrandom 0.4.2", "js-sys", "serde_core", - "sha1_smol", "wasm-bindgen", ] @@ -6641,6 +7023,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + [[package]] name = "version_check" version = "0.9.5" @@ -6665,18 +7053,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.4+wasi-0.2.12" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +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" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.128" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -6687,9 +7084,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.78" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ "js-sys", "wasm-bindgen", @@ -6697,9 +7094,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.128" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6707,26 +7104,60 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.128" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 3.0.6", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.128" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" 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 2.14.0", + "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 2.14.0", + "semver", +] + [[package]] name = "wasmtimer" version = "0.4.3" @@ -6743,13 +7174,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.17" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" +checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" dependencies = [ "cc", "downcast-rs", - "rustix 1.1.5", + "rustix 1.1.4", "scoped-tls", "smallvec", "wayland-sys", @@ -6757,12 +7188,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.15" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" +checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.13.2", - "rustix 1.1.5", + "bitflags 2.11.0", + "rustix 1.1.4", "wayland-backend", "wayland-scanner", ] @@ -6773,7 +7204,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cursor-icon", "wayland-backend", ] @@ -6784,18 +7215,18 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ - "rustix 1.1.5", + "rustix 1.1.4", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.32.13" +version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" +checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -6808,7 +7239,7 @@ version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6821,7 +7252,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6834,7 +7265,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6847,7 +7278,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6857,24 +7288,24 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.11" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" +checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", - "quick-xml", + "quick-xml 0.39.2", "quote", ] [[package]] name = "wayland-server" -version = "0.31.14" +version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde9c29be0f723a573977de51ee455bf3dfa03652730a74f9dd3b337e374d75" +checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "downcast-rs", - "rustix 1.1.5", + "rustix 1.1.4", "wayland-backend", "wayland-scanner", ] @@ -6893,9 +7324,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.105" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -6919,13 +7350,12 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" -version = "28.0.0" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" +checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" dependencies = [ "arrayvec", - "bitflags 2.13.2", - "bytemuck", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "document-features", @@ -6949,19 +7379,19 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "28.0.1" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23f4642f53f666adcfd2d3218ab174d1e6681101aef18696b90cbe64d1c10f9" +checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "cfg_aliases", "document-features", "hashbrown 0.16.1", - "indexmap 2.14.2", + "indexmap 2.14.0", "log", "naga", "once_cell", @@ -6971,7 +7401,7 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 2.0.20", + "thiserror 2.0.18", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", @@ -6981,42 +7411,42 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "28.0.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da" +checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "28.0.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79" +checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "28.0.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae" +checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "28.0.1" +version = "27.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d6cb474beb218824dcc9e1ce679d973f719262789bfb27407da560cac20eeb" +checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", - "bitflags 2.13.2", + "bitflags 2.11.0", "block", "bytemuck", "cfg-if", @@ -7024,6 +7454,7 @@ dependencies = [ "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", + "gpu-alloc", "gpu-allocator", "gpu-descriptor", "hashbrown 0.16.1", @@ -7046,24 +7477,25 @@ dependencies = [ "raw-window-handle", "renderdoc-sys", "smallvec", - "thiserror 2.0.20", + "thiserror 2.0.18", "wasm-bindgen", "web-sys", "wgpu-types", - "windows 0.62.2", - "windows-core 0.62.2", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] name = "wgpu-types" -version = "28.0.0" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" +checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "bytemuck", "js-sys", "log", + "thiserror 2.0.18", "web-sys", ] @@ -7101,10 +7533,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "clipboard-win", "clipboard_macos", "clipboard_wayland", + "clipboard_x11", "dnd", "mime 0.1.0", "raw-window-handle", @@ -7113,27 +7547,25 @@ dependencies = [ [[package]] name = "windows" -version = "0.61.3" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-collections 0.2.0", - "windows-core 0.61.2", - "windows-future 0.2.1", - "windows-link 0.1.3", - "windows-numerics 0.2.0", + "windows-core 0.58.0", + "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.62.2" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections 0.3.2", - "windows-core 0.62.2", - "windows-future 0.3.2", - "windows-numerics 0.3.1", + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", ] [[package]] @@ -7146,12 +7578,16 @@ dependencies = [ ] [[package]] -name = "windows-collections" -version = "0.3.2" +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-core 0.62.2", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] [[package]] @@ -7160,8 +7596,8 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", @@ -7173,8 +7609,8 @@ version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link 0.2.1", "windows-result 0.4.1", "windows-strings 0.5.1", @@ -7188,18 +7624,18 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading 0.1.0", + "windows-threading", ] [[package]] -name = "windows-future" -version = "0.3.2" +name = "windows-implement" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", - "windows-threading 0.2.1", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -7210,7 +7646,18 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -7221,7 +7668,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] @@ -7247,13 +7694,12 @@ dependencies = [ ] [[package]] -name = "windows-numerics" -version = "0.3.1" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", + "windows-targets 0.52.6", ] [[package]] @@ -7274,6 +7720,16 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -7394,15 +7850,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-threading" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -7544,14 +7991,15 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cfg_aliases", "cursor-icon", "dpi", "libc", "raw-window-handle", - "rustix 1.1.5", + "rustix 1.1.4", "smol_str", "tracing", "winit-android", @@ -7563,14 +8011,16 @@ dependencies = [ "winit-wayland", "winit-web", "winit-win32", + "winit-x11", ] [[package]] name = "winit-android" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "android-activity", - "bitflags 2.13.2", + "bitflags 2.11.0", "dpi", "ndk", "raw-window-handle", @@ -7582,8 +8032,9 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "dpi", @@ -7603,21 +8054,24 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "memmap2 0.9.11", + "memmap2 0.9.10", "objc2 0.6.4", "objc2-core-foundation", "smol_str", "tracing", "winit-core", + "x11-dl", "xkbcommon-dl", ] [[package]] name = "winit-core" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cursor-icon", "dpi", "keyboard-types", @@ -7629,13 +8083,14 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "dpi", "libredox", "orbclient", "raw-window-handle", - "redox_event", + "redox_syscall 0.7.4", "smol_str", "tracing", "winit-core", @@ -7644,8 +8099,9 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "dpi", @@ -7663,16 +8119,17 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "ahash", - "bitflags 2.13.2", + "bitflags 2.11.0", "calloop", "cursor-icon", "dpi", "libc", - "memmap2 0.9.11", + "memmap2 0.9.10", "raw-window-handle", - "rustix 1.1.5", + "rustix 1.1.4", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -7688,9 +8145,10 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "atomic-waker", - "bitflags 2.13.2", + "bitflags 2.11.0", "concurrent-queue", "cursor-icon", "dpi", @@ -7709,8 +8167,9 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "cursor-icon", "dpi", "raw-window-handle", @@ -7721,20 +8180,134 @@ dependencies = [ "winit-core", ] +[[package]] +name = "winit-x11" +version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +dependencies = [ + "bitflags 2.11.0", + "bytemuck", + "calloop", + "cursor-icon", + "dpi", + "libc", + "percent-encoding", + "raw-window-handle", + "rustix 1.1.4", + "smol_str", + "tracing", + "winit-common", + "winit-core", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" -version = "1.0.4" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.57.1" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +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 2.14.0", + "prettyplease", + "syn", + "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", + "syn", + "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 2.14.0", + "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 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "write16" @@ -7744,18 +8317,51 @@ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" -version = "0.6.4" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" dependencies = [ "either", ] [[package]] -name = "xcursor" -version = "0.3.11" +name = "x11-dl" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.4", + "x11rb-protocol", + "xcursor", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xcursor" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg" @@ -7765,7 +8371,8 @@ checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xdg-shell-wrapper-config" -version = "1.9.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel#d518c7d25ef96f1a9696aa8cce008656bf66ece4" dependencies = [ "serde", "wayland-protocols-wlr", @@ -7811,7 +8418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" dependencies = [ "libc", - "memmap2 0.9.11", + "memmap2 0.9.10", "xkeysym", ] @@ -7822,7 +8429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d" dependencies = [ "libc", - "memmap2 0.9.11", + "memmap2 0.9.10", "xkeysym", ] @@ -7832,7 +8439,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.13.2", + "bitflags 2.11.0", "dlib", "log", "once_cell", @@ -7850,15 +8457,15 @@ dependencies = [ [[package]] name = "xml" -version = "1.4.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f45bb2c13fec6a6cb4c0f76a7e94839e110a14ec803ec2940777a94c347bc52" +checksum = "b8aa498d22c9bbaf482329839bc5620c46be275a19a812e9a22a2b07529a642a" [[package]] name = "xml-rs" -version = "0.8.29" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" [[package]] name = "xmltree" @@ -7889,9 +8496,9 @@ checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -7900,21 +8507,21 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", - "synstructure 0.14.0", + "syn", + "synstructure", ] [[package]] name = "zbus" -version = "5.19.0" +version = "5.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907" +checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" dependencies = [ "async-broadcast", "async-executor", @@ -7932,7 +8539,7 @@ dependencies = [ "hex", "libc", "ordered-stream", - "rustix 1.1.5", + "rustix 1.1.4", "serde", "serde_repr", "tokio", @@ -7940,7 +8547,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", + "winnow 0.7.15", "zbus_macros", "zbus_names", "zvariant", @@ -7964,7 +8571,7 @@ checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", "zbus-lockstep", "zbus_xml", "zvariant", @@ -7972,14 +8579,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.19.0" +version = "5.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40" +checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.6", + "syn", "zbus_names", "zvariant", "zvariant_utils", @@ -7987,36 +8594,27 @@ dependencies = [ [[package]] name = "zbus_names" -version = "4.3.4" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" dependencies = [ "serde", - "winnow", + "winnow 0.7.15", "zvariant", ] [[package]] name = "zbus_xml" -version = "5.2.1" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" +checksum = "441a0064125265655bccc3a6af6bef56814d9277ac83fce48b1cd7e160b80eac" dependencies = [ + "quick-xml 0.38.4", "serde", - "winnow", "zbus_names", "zvariant", ] -[[package]] -name = "zcheapstr" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473" -dependencies = [ - "serde", -] - [[package]] name = "zeno" version = "0.3.3" @@ -8025,56 +8623,56 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.57" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.57" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn", ] [[package]] name = "zerofrom" -version = "0.1.8" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.8" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", - "synstructure 0.14.0", + "syn", + "synstructure", ] [[package]] name = "zeroize" -version = "1.9.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -8084,9 +8682,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.8" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "serde", "yoke", @@ -8096,93 +8694,20 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.6" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 3.0.6", -] - -[[package]] -name = "zlib-rs" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" - -[[package]] -name = "zlink" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b895b99588dceb73f4d349b8323eabad9a97d48ce83698d475c7223727c6148" -dependencies = [ - "zlink-smol", - "zlink-tokio", -] - -[[package]] -name = "zlink-core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd12701bd1d42a982b931f0159cf5054bf13d90e7828a8377dfc02ed4b00342d" -dependencies = [ - "futures-util", - "itoa", - "libc", - "pin-project-lite", - "rustix 1.1.5", - "ryu", - "serde", - "serde_json", - "tracing", - "zlink-macros", -] - -[[package]] -name = "zlink-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f2416a5f504dfd7e04fee49f31abafe3314a3f62b4ddaa8e9a5fd496d4dd50" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "zlink-smol" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc53cd0d636ad753f759aab0abb1f456e985c3938a279d11ebda92340ae37b1" -dependencies = [ - "async-broadcast", - "async-channel", - "async-io", - "futures-lite", - "futures-util", - "pin-project-lite", - "zlink-core", -] - -[[package]] -name = "zlink-tokio" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cbf366ac77ab41bf9a8d43535d3d620a072f7957813e03355d3d010c16cc4f" -dependencies = [ - "futures-util", - "pin-project-lite", - "tokio", - "tokio-stream", - "zlink-core", + "syn", ] [[package]] name = "zmij" -version = "1.0.23" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zune-core" @@ -8192,9 +8717,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] name = "zune-core" -version = "0.5.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" [[package]] name = "zune-jpeg" @@ -8211,55 +8736,46 @@ version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ - "zune-core 0.5.3", + "zune-core 0.5.1", ] [[package]] name = "zvariant" -version = "5.15.0" +version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d34c27cc6cdd1f458427519dd6b8612f7b7e3f7b9a0b2355d041dda9869147" +checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" dependencies = [ "endi", "enumflags2", "serde", "url", - "winnow", - "zcheapstr", + "winnow 0.7.15", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.15.0" +version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864155e69b4352db0c7f374917bf45d1e0c8d17659c8b3dbf9795f3673f8c497" +checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.6", + "syn", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "4.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" dependencies = [ "proc-macro2", "quote", "serde", - "syn 3.0.6", - "winnow", + "syn", + "winnow 0.7.15", ] - -[[patch.unused]] -name = "cosmic-settings-airplane-mode-subscription" -version = "1.9.0" - -[[patch.unused]] -name = "winit-x11" -version = "0.31.0-beta.2" diff --git a/Cargo.toml b/Cargo.toml index ab0c0004..5e6940de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ members = [ "cosmic-applet-minimize", "cosmic-applet-network", "cosmic-applet-notifications", - "cosmic-applet-osk", "cosmic-applet-power", "cosmic-applet-status-area", "cosmic-applet-tiling", @@ -26,12 +25,11 @@ resolver = "3" [workspace.dependencies] anyhow = "1.0.102" -cctk = { package = "cosmic-client-toolkit", path = "../cosmic-protocols/client-toolkit" } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "d0e95be" } cosmic-applets-config = { path = "cosmic-applets-config" } -cosmic-osk-config = { git = "https://github.com/pop-os/cosmic-osk" } -cosmic-protocols = { path = "../cosmic-protocols", default-features = false, features = [ +cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [ "client", -]} +], rev = "d0e95be" } futures = "0.3" futures-util = "0.3" @@ -40,7 +38,7 @@ i18n-embed = { version = "0.16.0", features = [ "desktop-requester", ] } i18n-embed-fl = "0.10" -cosmic = { package = "libcosmic-yoda", path = "../libcosmic", default-features = false, features = [ +libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = [ "applet", "applet-token", "dbus-config", @@ -50,7 +48,6 @@ cosmic = { package = "libcosmic-yoda", path = "../libcosmic", default-features = "desktop-systemd-scope", "winit", ] } -cosmic-comp-config = { path = "../cosmic-comp/cosmic-comp-config" } rust-embed = "8.11.0" rust-embed-utils = "8.11.0" rustc-hash = "2.1" @@ -61,14 +58,14 @@ tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } tracing-log = "0.2.0" tokio = { version = "1.49.0", features = ["full"] } # cosmic-config = { path = "../libcosmic/cosmic-config" } -cosmic-config = { path = "../libcosmic/cosmic-config" } +cosmic-config = { git = "https://github.com/pop-os/libcosmic" } serde = { version = "1.0.228", features = ["derive"] } -zlink = "0.5.0" [profile.release] -opt-level = 3 -panic = "abort" -lto = "thin" +# opt-level = 3 +# panic = "abort" +# lto = "thin" +opt-level = 1 [workspace.metadata.cargo-machete] ignored = ["libcosmic"] @@ -77,64 +74,22 @@ ignored = ["libcosmic"] # cosmic-config = { path = "../libcosmic/cosmic-config" } # libcosmic = { path = "../libcosmic" } # iced_futures = { path = "../libcosmic/iced/futures" } -# cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" } -# libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" } -# iced_futures = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" } +# cosmic-config = { git = "https://github.com/pop-os/libcosmic//" } +# libcosmic = { git = "https://github.com/pop-os/libcosmic//" } +# iced_futures = { git = "https://github.com/pop-os/libcosmic//" } -[patch."https://github.com/pop-os/libcosmic"] -cosmic-config = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-config" } -cosmic-theme = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-theme" } -iced = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced" } -iced_accessibility = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/accessibility" } -iced_core = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/core" } -iced_futures = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/futures" } -iced_graphics = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/graphics" } -iced_renderer = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/renderer" } -iced_runtime = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/runtime" } -iced_tiny_skia = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/tiny_skia" } -iced_wgpu = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/wgpu" } -iced_widget = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/widget" } -iced_winit = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/winit" } +# [patch."https://github.com/pop-os/winit.git"] +# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" } +# winit = { path = "../winit" } [patch."https://github.com/smithay/client-toolkit.git"] sctk = { package = "smithay-client-toolkit", version = "0.20.0" } [patch."https://github.com/pop-os/cosmic-protocols"] -cosmic-protocols = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols" } -cosmic-client-toolkit = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols/client-toolkit" } - -[patch."https://github.com/pop-os/cosmic-panel"] -cosmic-panel-config = { path = "/home/lionel/Projets/COSMIC/cosmic-panel/cosmic-panel-config" } -xdg-shell-wrapper-config = { path = "/home/lionel/Projets/COSMIC/cosmic-panel/xdg-shell-wrapper-config" } - -[patch."https://github.com/pop-os/cosmic-notifications"] -cosmic-notifications-config = { path = "/home/lionel/Projets/COSMIC/cosmic-notifications/cosmic-notifications-config" } -cosmic-notifications-util = { path = "/home/lionel/Projets/COSMIC/cosmic-notifications/cosmic-notifications-util" } - -[patch."https://github.com/pop-os/cosmic-settings"] -cosmic-settings-a11y-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/a11y-manager" } -cosmic-settings-accessibility-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/accessibility" } -cosmic-settings-airplane-mode-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/airplane-mode" } -cosmic-settings-daemon-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/settings-daemon" } -cosmic-settings-upower-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/upower" } - -[patch."https://github.com/pop-os/cosmic-settings/"] -cosmic-settings-airplane-mode-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/airplane-mode" } - -[patch."https://github.com/pop-os/cosmic-text.git"] -cosmic-text = { path = "../cosmic-text" } - -# Yoda: certaines crates amont 1.9 ecrivent l'URL avec "//" ; cargo la traite -# comme une source distincte, il faut donc la patcher aussi. -[patch."https://github.com/pop-os/cosmic-protocols//"] -cosmic-protocols = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols" } -cosmic-client-toolkit = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols/client-toolkit" } +cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols//", branch = "main" } +cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//", branch = "main" } # [patch.'https://github.com/pop-os/dbus-settings-bindings'] # cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" } # upower_dbus = { path = "../dbus-settings-bindings/upower" } # nm-secret-agent-manager = { path = "../dbus-settings-bindings/nm-secret-agent-manager" } - -# Yoda: cosmic-osk-config depuis le checkout local (meme source que le paquet cosmic-osk). -[patch."https://github.com/pop-os/cosmic-osk"] -cosmic-osk-config = { path = "../cosmic-osk/config" } diff --git a/cosmic-app-list/Cargo.toml b/cosmic-app-list/Cargo.toml index ad0edbd6..7c398b97 100644 --- a/cosmic-app-list/Cargo.toml +++ b/cosmic-app-list/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-app-list" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -13,13 +13,13 @@ futures.workspace = true i18n-embed.workspace = true i18n-embed-fl.workspace = true image = { version = "0.25.9", default-features = false } -cosmic.workspace = true +libcosmic.workspace = true memmap2 = "0.9.10" fastrand = "2.3.0" rust-embed.workspace = true rustix.workspace = true rustc-hash.workspace = true -switcheroo-control = { path = "../../dbus-settings-bindings/switcheroo-control" } +switcheroo-control = { git = "https://github.com/pop-os/dbus-settings-bindings" } tokio.workspace = true tracing-log.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-app-list/cosmic-app-list-config/Cargo.toml b/cosmic-app-list/cosmic-app-list-config/Cargo.toml index 78f48678..08d87f2e 100644 --- a/cosmic-app-list/cosmic-app-list-config/Cargo.toml +++ b/cosmic-app-list/cosmic-app-list-config/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "cosmic-app-list-config" -version = "1.9.0" +version = "1.0.2" edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmic.workspace = true +libcosmic.workspace = true serde = { workspace = true, features = ["derive"] } diff --git a/cosmic-app-list/i18n/ar/cosmic_app_list.ftl b/cosmic-app-list/i18n/ar/cosmic_app_list.ftl index f7aae84b..1e4d25cc 100644 --- a/cosmic-app-list/i18n/ar/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/ar/cosmic_app_list.ftl @@ -1,6 +1,6 @@ cosmic-app-list = دُرج التطبيقات pin = ثبِّت في درج التطبيقات -quit = إنهِ +quit = أنهِ quit-all = أنهِ الكل new-window = نافذة جديدة run = شغِّل diff --git a/cosmic-app-list/i18n/ca/cosmic_app_list.ftl b/cosmic-app-list/i18n/ca/cosmic_app_list.ftl index 340e296c..e69de29b 100644 --- a/cosmic-app-list/i18n/ca/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/ca/cosmic_app_list.ftl @@ -1,8 +0,0 @@ -new-window = Nova Finestra -quit = Surt -run = Executa -run-on = Executa a { $gpu } -quit-all = Surt de totes -run-on-default = (Per defecte) -cosmic-app-list = Safata d'Aplicacions -pin = Ancora a la safata diff --git a/cosmic-app-list/i18n/cs/cosmic_app_list.ftl b/cosmic-app-list/i18n/cs/cosmic_app_list.ftl index 5534149f..ad5b9257 100644 --- a/cosmic-app-list/i18n/cs/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/cs/cosmic_app_list.ftl @@ -1,5 +1,5 @@ -cosmic-app-list = Oblast aplikací -pin = Připnout do oblasti aplikací +cosmic-app-list = Panel aplikací +pin = Připnout do panelu aplikací quit = Ukončit quit-all = Ukončit vše new-window = Nové okno diff --git a/cosmic-app-list/i18n/da/cosmic_app_list.ftl b/cosmic-app-list/i18n/da/cosmic_app_list.ftl index 3396ed61..e69de29b 100644 --- a/cosmic-app-list/i18n/da/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/da/cosmic_app_list.ftl @@ -1,8 +0,0 @@ -run = Kør -run-on = Kør på { $gpu } -run-on-default = (Standard) -cosmic-app-list = Programbakke -new-window = Nyt Vindue -quit = Afslut -quit-all = Forlad Alle -pin = Fastgør til app-skuffe diff --git a/cosmic-app-list/i18n/el/cosmic_app_list.ftl b/cosmic-app-list/i18n/el/cosmic_app_list.ftl index 0b8a7fb6..6a425d48 100644 --- a/cosmic-app-list/i18n/el/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/el/cosmic_app_list.ftl @@ -1,8 +1 @@ new-window = Νέο παράθυρο -quit = Τερματισμός -cosmic-app-list = Περιοχή εφαρμογών -run = Εκτέλεση -run-on = Εκτέλεση με { $gpu } -quit-all = Έξοδος από όλα -run-on-default = (Προεπιλογή) -pin = Καρφίτσωμα στην περιοχή εφαρμογών diff --git a/cosmic-app-list/i18n/en-GB/cosmic_app_list.ftl b/cosmic-app-list/i18n/en-GB/cosmic_app_list.ftl index f3afe950..e69de29b 100644 --- a/cosmic-app-list/i18n/en-GB/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/en-GB/cosmic_app_list.ftl @@ -1,8 +0,0 @@ -cosmic-app-list = App Tray -new-window = New Window -quit = Quit -run = Run -run-on = Run on { $gpu } -quit-all = Quit All -run-on-default = (Default) -pin = Pin to app tray diff --git a/cosmic-app-list/i18n/en/cosmic_app_list.ftl b/cosmic-app-list/i18n/en/cosmic_app_list.ftl index 028a1558..c412cd51 100644 --- a/cosmic-app-list/i18n/en/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/en/cosmic_app_list.ftl @@ -5,15 +5,4 @@ quit-all = Quit All new-window = New Window run = Run run-on = Run on {$gpu} -run-on-default = (Default) -edit-launcher = Edit launcher -launcher-name = Name -launcher-command = Command -launcher-icon = Icon -launcher-icon-theme = Theme -launcher-icon-search = Search icons -launcher-icon-catalog-loading = Loading icons -launcher-icon-catalog-empty = No icons -launcher-icons = icons -save = Save -cancel = Cancel +run-on-default = (Default) \ No newline at end of file diff --git a/cosmic-app-list/i18n/fa/cosmic_app_list.ftl b/cosmic-app-list/i18n/fa/cosmic_app_list.ftl index 8d098db3..be2d279a 100644 --- a/cosmic-app-list/i18n/fa/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/fa/cosmic_app_list.ftl @@ -1,8 +1,8 @@ -cosmic-app-list = نوار برنامه‌ها -pin = افزودن به نوار برنامه‌ها -quit = خروج -quit-all = خروج از همه +cosmic-app-list = سینی برنامه‌ها +pin = سنجاق کردن به سینی برنامه‌ها +quit = بستن +quit-all = بستن همه new-window = پنجره جدید run = اجرا -run-on = اجرا با { $gpu } -run-on-default = (پیش‌فرض) +run-on = اجرا روی {$gpu} +run-on-default = (پیش‌فرض) \ No newline at end of file diff --git a/cosmic-app-list/i18n/fil/cosmic_app_list.ftl b/cosmic-app-list/i18n/fil/cosmic_app_list.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl index 16bb7465..a065b203 100644 --- a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl @@ -3,17 +3,6 @@ pin = Épingler à la barre d'applis quit = Quitter quit-all = Tout quitter new-window = Nouvelle fenêtre -run = Exécuter +run = Lancer run-on = Lancer avec { $gpu } run-on-default = (Défaut) -edit-launcher = Modifier le lanceur -launcher-name = Nom -launcher-command = Commande -launcher-icon = Icône -launcher-icon-theme = Thème -launcher-icon-search = Rechercher une icône -launcher-icon-catalog-loading = Chargement des icônes -launcher-icon-catalog-empty = Aucune icône -launcher-icons = icônes -save = Enregistrer -cancel = Annuler diff --git a/cosmic-app-list/i18n/gl/cosmic_app_list.ftl b/cosmic-app-list/i18n/gl/cosmic_app_list.ftl deleted file mode 100644 index 4fa947a7..00000000 --- a/cosmic-app-list/i18n/gl/cosmic_app_list.ftl +++ /dev/null @@ -1,8 +0,0 @@ -quit = Pechar -run = Executar -cosmic-app-list = Bandexa de aplicacións -pin = Fixar na bandexa de aplicacións -quit-all = Quitar todo -new-window = Nova Xanela -run-on = Executar en { $gpu } -run-on-default = (Por defecto) diff --git a/cosmic-app-list/i18n/hi/cosmic_app_list.ftl b/cosmic-app-list/i18n/hi/cosmic_app_list.ftl index 2c6b12a3..88138ea6 100644 --- a/cosmic-app-list/i18n/hi/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/hi/cosmic_app_list.ftl @@ -1,8 +1,8 @@ cosmic-app-list = ऐप ट्रे pin = ऐप ट्रे में पिन करें -quit = बाहर जाएँ +quit = बंद करें quit-all = सभी बंद करें new-window = नई विंडो run = चलाएँ -run-on = { $gpu } पर चलाएँ +run-on = {$gpu} पर चलाएँ run-on-default = (डिफ़ॉल्ट) diff --git a/cosmic-app-list/i18n/it/cosmic_app_list.ftl b/cosmic-app-list/i18n/it/cosmic_app_list.ftl index b65b4e23..96a5b575 100644 --- a/cosmic-app-list/i18n/it/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/it/cosmic_app_list.ftl @@ -1,8 +1,8 @@ -cosmic-app-list = Area applicazioni +cosmic-app-list = Barra applicazioni pin = Fissa nella barra delle applicazioni quit = Esci quit-all = Chiudi tutto new-window = Nuova finestra run = Esegui -run-on = Esegui su { $gpu } -run-on-default = (Predefinito) +run-on = Esegui usando la GPU: { $gpu } +run-on-default = (default) diff --git a/cosmic-app-list/i18n/kab/cosmic_app_list.ftl b/cosmic-app-list/i18n/kab/cosmic_app_list.ftl index a6141b52..0d7b0d15 100644 --- a/cosmic-app-list/i18n/kab/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/kab/cosmic_app_list.ftl @@ -1,7 +1,7 @@ run = Selkem run-on = Selkem ɣef { $gpu } run-on-default = (Amezwer) -quit = Ffeɣ +quit = Tuffɣa quit-all = Ffeɣ-iten akk new-window = Asfaylu Amaynut cosmic-app-list = Afeggag n yisnasen diff --git a/cosmic-app-list/i18n/kk/cosmic_app_list.ftl b/cosmic-app-list/i18n/kk/cosmic_app_list.ftl index a1b070a2..c0e5a033 100644 --- a/cosmic-app-list/i18n/kk/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/kk/cosmic_app_list.ftl @@ -1,5 +1,5 @@ quit = Шығу -run = Орындау +run = Іске қосу run-on = { $gpu } арқылы іске қосу run-on-default = (Әдепкі) cosmic-app-list = Қолданбалар сөресі diff --git a/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl b/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl index 793d1880..e69de29b 100644 --- a/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl @@ -1,8 +0,0 @@ -run = Bixebitîne -run-on = Li ser { $gpu } bixebitîne -run-on-default = (Berdest) -pin = Bo destgeha sepanan bi dar bixe -quit = Biqedîne -quit-all = Hemûyan biqedîne -new-window = Çarçoveya nû -cosmic-app-list = Destgeha sepanan diff --git a/cosmic-app-list/i18n/lo/cosmic_app_list.ftl b/cosmic-app-list/i18n/lo/cosmic_app_list.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-app-list/i18n/lt/cosmic_app_list.ftl b/cosmic-app-list/i18n/lt/cosmic_app_list.ftl index 25dd5990..c86f45a1 100644 --- a/cosmic-app-list/i18n/lt/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/lt/cosmic_app_list.ftl @@ -1,5 +1,5 @@ new-window = Naujas Langas -quit = Išjungti +quit = Išeiti run = Paleisti run-on = Paleisti naudojantis { $gpu } run-on-default = (Numatytas) diff --git a/cosmic-app-list/i18n/oc/cosmic_app_list.ftl b/cosmic-app-list/i18n/oc/cosmic_app_list.ftl index ebf18389..e69de29b 100644 --- a/cosmic-app-list/i18n/oc/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/oc/cosmic_app_list.ftl @@ -1,3 +0,0 @@ -cosmic-app-list = Cinta d’aplicacions -quit = Quitar -run = Executar diff --git a/cosmic-app-list/i18n/pa/cosmic_app_list.ftl b/cosmic-app-list/i18n/pa/cosmic_app_list.ftl index cb202e4b..ab835da6 100644 --- a/cosmic-app-list/i18n/pa/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/pa/cosmic_app_list.ftl @@ -1,4 +1,4 @@ -quit = ਸਮਾਪਤ +quit = ਬਾਹਰ cosmic-app-list = ਐਪ ਟਰੇ pin = ਐਪ ਟਰੇ ਵਿੱਚ ਟੰਗੋ quit-all = ਸਭ ਵਿੱਚੋਂ ਬਾਹਰ diff --git a/cosmic-app-list/i18n/pl/cosmic_app_list.ftl b/cosmic-app-list/i18n/pl/cosmic_app_list.ftl index d619a422..aaedc5f0 100644 --- a/cosmic-app-list/i18n/pl/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/pl/cosmic_app_list.ftl @@ -1,6 +1,6 @@ cosmic-app-list = Zasobnik aplikacji pin = Przypnij do zasobnika aplikacji -quit = Zakończ +quit = Zamknij quit-all = Zamknij wszystkie new-window = Nowe okno run = Uruchom diff --git a/cosmic-app-list/i18n/pt-BR/cosmic_app_list.ftl b/cosmic-app-list/i18n/pt-BR/cosmic_app_list.ftl index 0a28b697..2b94e0e9 100644 --- a/cosmic-app-list/i18n/pt-BR/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/pt-BR/cosmic_app_list.ftl @@ -1,6 +1,6 @@ cosmic-app-list = Bandeja de aplicativos pin = Fixar na bandeja de aplicativos -quit = Encerrar +quit = Sair quit-all = Sair de Todos new-window = Nova Janela run = Executar diff --git a/cosmic-app-list/i18n/ru/cosmic_app_list.ftl b/cosmic-app-list/i18n/ru/cosmic_app_list.ftl index 0a21e1fe..a7d98a5b 100644 --- a/cosmic-app-list/i18n/ru/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/ru/cosmic_app_list.ftl @@ -1,6 +1,6 @@ cosmic-app-list = Область приложений pin = Закрепить на панели приложений -quit = Завершить +quit = Выйти quit-all = Завершить все new-window = Новое окно run = Запустить diff --git a/cosmic-app-list/i18n/sat/cosmic_app_list.ftl b/cosmic-app-list/i18n/sat/cosmic_app_list.ftl deleted file mode 100644 index 32be0db1..00000000 --- a/cosmic-app-list/i18n/sat/cosmic_app_list.ftl +++ /dev/null @@ -1,2 +0,0 @@ -run-on = { $gpu } ᱨᱮ ᱫᱟᱹᱲ ᱟᱭ -run-on-default = (ᱢᱩᱞ) diff --git a/cosmic-app-list/i18n/sr/cosmic_app_list.ftl b/cosmic-app-list/i18n/sr/cosmic_app_list.ftl index 4cf077b9..e69de29b 100644 --- a/cosmic-app-list/i18n/sr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/sr/cosmic_app_list.ftl @@ -1,8 +0,0 @@ -new-window = Нови прозор -quit = Изађи -run = Покрени -run-on = Покрени на { $gpu } -quit-all = Изађи из свега -run-on-default = (подразумевано) -cosmic-app-list = Системска касета -pin = Закачи у системску касету diff --git a/cosmic-app-list/i18n/uk/cosmic_app_list.ftl b/cosmic-app-list/i18n/uk/cosmic_app_list.ftl index b6aea1f1..aed01bf2 100644 --- a/cosmic-app-list/i18n/uk/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/uk/cosmic_app_list.ftl @@ -1,8 +1,8 @@ cosmic-app-list = Панель застосунків pin = Закріпити -quit = Завершити +quit = Вийти quit-all = Закрити всі new-window = Нове вікно -run = Виконати +run = Запустити run-on = Запустити на { $gpu } run-on-default = (Основна) diff --git a/cosmic-app-list/i18n/zh-TW/cosmic_app_list.ftl b/cosmic-app-list/i18n/zh-TW/cosmic_app_list.ftl index c29bd8a5..9595d3b0 100644 --- a/cosmic-app-list/i18n/zh-TW/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/zh-TW/cosmic_app_list.ftl @@ -1,8 +1,8 @@ -cosmic-app-list = 應用程式托盤 -pin = 釘選至應用程式托盤 -quit = 結束 +cosmic-app-list = 應用程式匣盤 +pin = 釘選至應用程式匣盤 +quit = 退出 quit-all = 全部退出 -new-window = 新增視窗 +new-window = 新建視窗 run = 執行 run-on = 在 { $gpu } 上執行 run-on-default = (預設) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index facd8267..932ffd6c 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -2,8 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - fl, icon_catalog, - launcher_edit::{self, LauncherEditRequest}, + fl, wayland_subscription::{ OutputUpdate, ToplevelRequest, ToplevelUpdate, WaylandImage, WaylandRequest, WaylandUpdate, wayland_subscription, @@ -28,30 +27,27 @@ use cosmic::{ }, cosmic_config::{Config, CosmicConfigEntry}, desktop::IconSourceExt, + iced::runtime::{core::event, dnd::peek_dnd}, iced::{ self, Alignment, Background, Border, Length, Limits, Padding, Subscription, advanced::text::{Ellipsize, EllipsizeHeightLimit}, clipboard::mime::{AllowedMimeTypes, AsMimeTypes}, event::listen_with, platform_specific::shell::commands::popup::{destroy_popup, get_popup}, - runtime::{core::event, dnd::peek_dnd, platform_specific::wayland::CornerRadius}, widget::{ - Column, Row, column, mouse_area, row, - rule::vertical as vertical_rule, - space::{horizontal as horizontal_space, vertical as vertical_space}, - stack, + Column, Row, column, mouse_area, row, rule::vertical as vertical_rule, + space::horizontal as horizontal_space, space::vertical as vertical_space, stack, }, window, }, - surface::{self, action::LiveSettings}, + surface, theme::{self, Button, Container}, widget::{ - DndDestination, Image, button, container, divider, dnd_source, grid, + DndDestination, Image, button, container, divider, dnd_source, icon::{self, from_name}, image::Handle, - menu, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, - scrollable, svg, text, text_input, + svg, text, }, }; use cosmic::{ @@ -68,8 +64,6 @@ use tokio::time::sleep; use url::Url; static MIME_TYPE: &str = "text/uri-list"; -const MAX_VISIBLE_ICON_CHOICES: usize = 120; -const ICON_CATALOG_COLUMNS: usize = 6; pub fn run() -> cosmic::iced::Result { cosmic::applet::run::(()) @@ -193,11 +187,6 @@ impl DockItem { dot_border_radius: [f32; 4], window_id: window::Id, filter: Option<&dyn Fn(&ToplevelInfo) -> bool>, - // Yoda: multiplier on the computed icon size (1.0 = default, - // >1.0 = magnified e.g. on hover for the macOS Tahoe effect). - // Applied to the icon's rendered width/height only — indicator - // dot and surrounding layout stay at base size. - icon_scale: f32, ) -> Element<'_, Message> { let Self { toplevels, @@ -216,35 +205,17 @@ impl DockItem { }; let toplevel_count = filtered_toplevels.len(); - // Cairo-like : pastille plus petite + atténuée quand toutes les fenêtres - // de cette app sont minimisées. - let all_minimized = toplevel_count > 0 - && filtered_toplevels - .iter() - .all(|(info, _)| info.state.contains(&State::Minimized)); - let app_icon = AppletIconData::new(applet); - // Yoda: scaled icon size for hover magnification. Clamped so - // tiny floats don't round to 0 and huge ones stay within u16. - let scaled_icon_size = ((f32::from(app_icon.icon_size) * icon_scale).round() as i32) - .clamp(1, u16::MAX as i32) as u16; let cosmic_icon = cosmic::widget::icon( fde::IconSource::from_unknown(desktop_info.icon().unwrap_or_default()).as_cosmic_icon(), ) // sets the preferred icon size variant .size(128) - .width(scaled_icon_size.into()) - .height(scaled_icon_size.into()); + .width(app_icon.icon_size.into()) + .height(app_icon.icon_size.into()); let indicator = { - // Padding réduit quand minimisée → pastille plus petite. - let effective_radius = if all_minimized { - (app_icon.dot_radius * 0.55).max(1.0) - } else { - app_icon.dot_radius - }; - let container = if toplevel_count <= 1 { vertical_space().height(Length::Fixed(0.0)) } else { @@ -258,34 +229,22 @@ impl DockItem { } } .apply(container) - .padding(effective_radius); + .padding(app_icon.dot_radius); if toplevel_count == 0 { container } else { - container.class(theme::Container::custom(move |theme| { - let cosmic = theme.cosmic(); - let accent: iced::Color = cosmic.accent_color().into(); - let on_bg: iced::Color = cosmic.on_bg_color().into(); - // Teinte neutre atténuée quand toutes les fenêtres sont minimisées. - let muted = iced::Color { a: 0.45, ..on_bg }; - - let fill = if all_minimized { - muted - } else if is_focused { - accent + container.class(theme::Container::custom(move |theme| container::Style { + background: if is_focused { + Some(Background::Color(theme.cosmic().accent_color().into())) } else { - on_bg - }; - - container::Style { - background: Some(Background::Color(fill)), - border: Border { - radius: dot_border_radius.into(), - ..Default::default() - }, + Some(Background::Color(theme.cosmic().on_bg_color().into())) + }, + border: Border { + radius: dot_border_radius.into(), ..Default::default() - } + }, + ..Default::default() })) } }; @@ -393,35 +352,10 @@ pub struct Popup { popup_type: PopupType, } -#[derive(Debug, Clone)] -struct LauncherEditState { - original_app_id: String, - source_path: PathBuf, - original_name: String, - original_exec: String, - name: String, - exec: String, - icon: String, - terminal: bool, - saving: bool, - error: Option, - icon_catalog: IconCatalogState, -} - -#[derive(Debug, Clone)] -struct IconCatalogState { - theme: String, - query: String, - entries: Vec, - loading: bool, - truncated: bool, -} - #[derive(Clone, Default)] struct CosmicAppList { core: cosmic::app::Core, popup: Option, - launcher_edit: Option, subscription_ctr: u32, item_ctr: u32, desktop_entries: Vec, @@ -440,21 +374,6 @@ struct CosmicAppList { output_list: FxHashMap, locales: Vec, hovered_toplevel: Option, - /// Yoda: which dock icon the pointer is currently over (for hover - /// magnification). None = no dock icon hovered. - hovered_dock_item: Option, - /// Yoda: animated "virtual cursor" center used by the fisheye - /// formula — lerps toward the real hovered icon's center on each - /// AnimTick, so the bell curve slides smoothly from one icon to the - /// next instead of snapping. - anim_hover_center: Option<(f32, f32)>, - /// Yoda: fade-in/out intensity of the magnification effect - /// (0.0 = icons flat, 1.0 = full fisheye). Targets 1.0 while the - /// pointer is over any dock icon, 0.0 otherwise. Lerped on AnimTick. - anim_hover_intensity: f32, - /// Yoda: timestamp of the last AnimTick, for dt-based exponential - /// smoothing. `None` on first tick. - anim_last_tick: Option, overflow_favorites_popup: Option, overflow_active_popup: Option, } @@ -463,33 +382,13 @@ struct CosmicAppList { pub enum PopupType { RightClickMenu, ToplevelList, - LauncherEditor, } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { Wayland(WaylandUpdate), PinApp(u32), UnpinApp(u32), - EditLauncher(u32), - LauncherNameChanged(String), - LauncherExecChanged(String), - LauncherIconChanged(String), - LauncherIconSearchChanged(String), - LauncherIconSelected(String), - ReloadLauncherIconCatalog, - LauncherIconCatalogLoaded(icon_catalog::IconCatalog), - SaveLauncherEdit, - CancelLauncherEdit, - LauncherEditSaved(Result), - /// Yoda: pointer entered (Some) or left (None) a dock icon — drives - /// the macOS Tahoe-style hover magnification effect. - DockItemHover(Option), - /// Yoda: ticked at ~60fps by the animation subscription. Advances - /// anim_hover_center + anim_hover_intensity toward their targets so - /// the fisheye effect transitions smoothly instead of snapping. - AnimTick(std::time::Instant), Popup(u32, window::Id), Pressed(window::Id), ToplevelListPopup(u32, window::Id), @@ -518,7 +417,7 @@ enum Message { ConfigUpdated(AppListConfig), OpenFavorites, OpenActive, - Surface(surface::Action), + Surface(surface::Action), } fn index_in_list( @@ -727,143 +626,6 @@ pub fn menu_control_padding() -> Padding { [spacing.space_xxs, spacing.space_s].into() } -fn launcher_icon_editor(edit: &LauncherEditState) -> Element<'_, Message> { - let spacing = theme::spacing(); - let selected_icon = edit.icon.trim(); - let query = edit.icon_catalog.query.trim().to_ascii_lowercase(); - let mut total_matches = 0usize; - let mut visible_count = 0usize; - let mut icon_grid = grid() - .width(Length::Fill) - .column_spacing(spacing.space_xxs) - .row_spacing(spacing.space_xxs); - - for entry in edit.icon_catalog.entries.iter().filter(|entry| { - query.is_empty() || entry.name.to_ascii_lowercase().contains(query.as_str()) - }) { - total_matches += 1; - if visible_count >= MAX_VISIBLE_ICON_CHOICES { - continue; - } - - if visible_count > 0 && visible_count % ICON_CATALOG_COLUMNS == 0 { - icon_grid = icon_grid.insert_row(); - } - - let selected = selected_icon == entry.name; - let icon_preview = cosmic::widget::icon( - fde::IconSource::from_unknown(entry.name.as_str()).as_cosmic_icon(), - ) - .size(32) - .width(Length::Fixed(32.0)) - .height(Length::Fixed(32.0)); - - let label = text::caption(entry.name.as_str()) - .ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(1))) - .width(Length::Fill) - .center(); - - let tile = column![icon_preview, label] - .align_x(Alignment::Center) - .spacing(4) - .width(Length::Fixed(70.0)); - - let tile_button = button::custom(tile) - .class(if selected { - Button::Suggested - } else { - Button::Image - }) - .selected(selected) - .on_press(Message::LauncherIconSelected(entry.name.clone())) - .padding(6) - .width(Length::Fixed(74.0)) - .height(Length::Fixed(76.0)); - - icon_grid = icon_grid.push(tile_button); - visible_count += 1; - } - - let current_icon = - cosmic::widget::icon(fde::IconSource::from_unknown(edit.icon.as_str()).as_cosmic_icon()) - .size(32) - .width(Length::Fixed(36.0)) - .height(Length::Fixed(36.0)); - - let icon_value = row![ - current_icon, - text_input("", edit.icon.as_str()) - .label(fl!("launcher-icon")) - .on_input(Message::LauncherIconChanged) - .on_submit(|_| Message::SaveLauncherEdit) - .width(Length::Fill) - .size(14), - button::icon(from_name("view-refresh-symbolic")) - .on_press(Message::ReloadLauncherIconCatalog) - .padding(spacing.space_xxs), - ] - .spacing(spacing.space_xs) - .align_y(Alignment::Center); - - let visible_total = if edit.icon_catalog.truncated { - format!( - "{}/{}+ {}", - visible_count, - total_matches, - fl!("launcher-icons") - ) - } else { - format!( - "{}/{} {}", - visible_count, - total_matches, - fl!("launcher-icons") - ) - }; - - let catalog_header = row![ - text::caption(format!( - "{}: {}", - fl!("launcher-icon-theme"), - edit.icon_catalog.theme - )), - horizontal_space(), - text::caption(visible_total), - ] - .align_y(Alignment::Center); - - let catalog_body: Element<_> = if edit.icon_catalog.loading { - container(text::body(fl!("launcher-icon-catalog-loading"))) - .center(Length::Fill) - .height(Length::Fixed(220.0)) - .into() - } else if total_matches == 0 { - container(text::body(fl!("launcher-icon-catalog-empty"))) - .center(Length::Fill) - .height(Length::Fixed(220.0)) - .into() - } else { - scrollable(icon_grid) - .height(Length::Fixed(240.0)) - .width(Length::Fill) - .into() - }; - - column![ - icon_value, - catalog_header, - text_input("", edit.icon_catalog.query.as_str()) - .label(fl!("launcher-icon-search")) - .on_input(Message::LauncherIconSearchChanged) - .width(Length::Fill) - .size(14), - catalog_body, - ] - .spacing(spacing.space_s) - .width(Length::Fill) - .into() -} - fn find_desktop_entries<'a>( desktop_entries: &'a [fde::DesktopEntry], app_ids: &'a [String], @@ -885,79 +647,6 @@ impl CosmicAppList { .collect::>(); } - /// Yoda: macOS-Tahoe fisheye-style magnification. Returns the - /// per-icon size multiplier based on the distance (in pixels) from - /// the currently hovered icon's center to this icon's center. - /// - /// Uses a gaussian bell curve so the hovered icon peaks at - /// 1.0 + PEAK, immediate neighbors still bulge noticeably, and icons - /// further away relax back to 1.0× — that's the smooth neighbour - /// deformation people associate with the macOS Dock. - /// - /// Falls back to binary 1.3×/1.0× when the rectangle tracker hasn't - /// populated yet (first render, or just after layout changes). - /// - /// Uses the animated hover center (anim_hover_center) and intensity - /// (anim_hover_intensity) so inter-icon transitions slide smoothly - /// and the whole effect fades in/out at the dock's edges. - fn icon_scale_for(&self, id: &DockItemId) -> f32 { - const PEAK: f32 = 0.35; - // sigma expressed in multiples of the hovered icon's size — - // 1.4 means the ±1 neighbors sit ~0.7σ away and still bulge - // visibly, while ±3+ has collapsed to ~1.0× (fisheye footprint - // close to 5 icons wide, Tahoe-ish). - const SIGMA_FACTOR: f32 = 1.4; - - // No intensity at all → skip the rest. - if self.anim_hover_intensity < 0.001 { - return 1.0; - } - - // Prefer the animated center (smooth); fall back to the real - // hovered icon's center (first render, before tick fires). - let hover_center = self.anim_hover_center.or_else(|| { - let hovered_id = self.hovered_dock_item.as_ref()?; - let r = self.rectangles.get(hovered_id)?; - Some((r.x + r.width / 2.0, r.y + r.height / 2.0)) - }); - let Some(hover_center) = hover_center else { - // No coords yet — visibly peak on the exact hovered id so - // the very first frame still responds. - return if self.hovered_dock_item.as_ref() == Some(id) { - 1.0 + PEAK * self.anim_hover_intensity - } else { - 1.0 - }; - }; - - let this_rect = match self.rectangles.get(id) { - Some(r) => r, - None => return 1.0, - }; - - let is_horizontal = matches!( - self.core.applet.anchor, - PanelAnchor::Top | PanelAnchor::Bottom - ); - let this_center = if is_horizontal { - this_rect.x + this_rect.width / 2.0 - } else { - this_rect.y + this_rect.height / 2.0 - }; - let hover_axis = if is_horizontal { hover_center.0 } else { hover_center.1 }; - let distance = (this_center - hover_axis).abs(); - let icon_extent = if is_horizontal { - this_rect.width - } else { - this_rect.height - } - .max(1.0); - let sigma = icon_extent * SIGMA_FACTOR; - // exp(-t²) bell curve, t = distance / sigma - let t = distance / sigma; - 1.0 + PEAK * self.anim_hover_intensity * (-t * t).exp() - } - fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool { use cosmic_app_list_config::ToplevelFilter; @@ -1002,45 +691,10 @@ impl CosmicAppList { .collect(); } - fn sync_pinned_list_from_config(&mut self) { - for item in self.pinned_list.drain(..) { - if !item.toplevels.is_empty() { - self.active_list.push(item); - } - } - - self.pinned_list = find_desktop_entries(&self.desktop_entries, &self.config.favorites) - .zip(&self.config.favorites) - .map(|(de, original_id)| { - if let Some(p) = self - .active_list - .iter() - .position(|dock_item| dock_item.desktop_info.id() == de.id()) - { - let mut d = self.active_list.remove(p); - d.desktop_info = de.clone(); - d.original_app_id.clone_from(original_id); - d - } else { - self.item_ctr += 1; - DockItem { - id: self.item_ctr, - toplevels: Vec::new(), - desktop_info: de.clone(), - original_app_id: original_id.clone(), - } - } - }) - .collect(); - } - /// Close any open popups. fn close_popups(&mut self) -> Task> { let mut commands = Vec::new(); if let Some(popup) = self.popup.take() { - if popup.popup_type == PopupType::LauncherEditor { - self.launcher_edit = None; - } commands.push(destroy_popup(popup.id)); } if let Some(popup) = self.overflow_active_popup.take() { @@ -1252,54 +906,44 @@ impl cosmic::Application for CosmicAppList { .iter() .chain(self.pinned_list.iter()) .find(|t| t.id == id) - .cloned() { - let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied() - else { + let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { tracing::error!("No rectangle found for toplevel group"); return Task::none(); }; - let corners = self.core.system_theme().cosmic().corner_radii.radius_s; - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - move |_| LiveSettings::default(), - move |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup = Some(Popup { - parent: parent_window_id, - id: new_id, - dock_item: toplevel_group.clone(), - popup_type: PopupType::RightClickMenu, - }); - let mut popup_settings = app.core.applet.get_popup_settings( - parent_window_id, - new_id, - None, - None, - None, - ); - let iced::Rectangle { - x, - y, - width, - height, - } = rectangle; - popup_settings.positioner.anchor_rect = iced::Rectangle:: { - x: x as i32, - y: y as i32, - width: width as i32, - height: height as i32, - }; - popup_settings - }, - None, - )); + let new_id = window::Id::unique(); + self.popup = Some(Popup { + parent: parent_window_id, + id: new_id, + dock_item: toplevel_group.clone(), + popup_type: PopupType::RightClickMenu, + }); + + let mut popup_settings = self.core.applet.get_popup_settings( + parent_window_id, + new_id, + None, + None, + None, + ); + let iced::Rectangle { + x, + y, + width, + height, + } = *rectangle; + popup_settings.positioner.anchor_rect = iced::Rectangle:: { + x: x as i32, + y: y as i32, + width: width as i32, + height: height as i32, + }; let gpu_update = Task::perform(try_get_gpus(), |gpus| { cosmic::Action::App(Message::GpuRequest(gpus)) }); - return Task::batch([gpu_update, popup_task]); + return Task::batch([gpu_update, get_popup(popup_settings)]); } } Message::ToplevelListPopup(id, parent_window_id) => { @@ -1330,10 +974,10 @@ impl cosmic::Application for CosmicAppList { } } - let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied() - else { + let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { return Task::none(); }; + let new_id = window::Id::unique(); self.popup = Some(Popup { parent: parent_window_id, @@ -1341,56 +985,48 @@ impl cosmic::Application for CosmicAppList { dock_item: toplevel_group.clone(), popup_type: PopupType::ToplevelList, }); - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let mut popup_settings = app.core.applet.get_popup_settings( - parent_window_id, - new_id, - None, - None, - None, - ); - let iced::Rectangle { - x, - y, - width, - height, - } = rectangle; - popup_settings.positioner.anchor_rect = iced::Rectangle:: { - x: x as i32, - y: y as i32, - width: width as i32, - height: height as i32, - }; - let max_windows = 7.0; - let window_spacing = 8.0; - popup_settings.positioner.size_limits = match app.core.applet.anchor - { - PanelAnchor::Right | PanelAnchor::Left => Limits::NONE - .min_width(100.0) - .min_height(30.0) - .max_width(window_spacing * 2.0 + TOPLEVEL_BUTTON_WIDTH) - .max_height( - TOPLEVEL_BUTTON_HEIGHT * max_windows - + window_spacing * (max_windows + 1.0), - ), - PanelAnchor::Bottom | PanelAnchor::Top => Limits::NONE - .min_width(30.0) - .min_height(100.0) - .max_width( - TOPLEVEL_BUTTON_WIDTH * max_windows - + window_spacing * (max_windows + 1.0), - ) - .max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT), - }; - popup_settings - }, - None, - )); - return popup_task; + let mut popup_settings = self.core.applet.get_popup_settings( + parent_window_id, + new_id, + None, + None, + None, + ); + let iced::Rectangle { + x, + y, + width, + height, + } = *rectangle; + popup_settings.positioner.anchor_rect = iced::Rectangle:: { + x: x as i32, + y: y as i32, + width: width as i32, + height: height as i32, + }; + let max_windows = 7.0; + let window_spacing = 8.0; + popup_settings.positioner.size_limits = match self.core.applet.anchor { + PanelAnchor::Right | PanelAnchor::Left => Limits::NONE + .min_width(100.0) + .min_height(30.0) + .max_width(window_spacing * 2.0 + TOPLEVEL_BUTTON_WIDTH) + .max_height( + TOPLEVEL_BUTTON_HEIGHT * max_windows + + window_spacing * (max_windows + 1.0), + ), + PanelAnchor::Bottom | PanelAnchor::Top => Limits::NONE + .min_width(30.0) + .min_height(100.0) + .max_width( + TOPLEVEL_BUTTON_WIDTH * max_windows + + window_spacing * (max_windows + 1.0), + ) + .max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT), + }; + + return get_popup(popup_settings); } } Message::ToplevelHoverChanged(handle, entering) => { @@ -1432,198 +1068,6 @@ impl cosmic::Application for CosmicAppList { return destroy_popup(popup_id); } } - Message::EditLauncher(id) => { - let Some(dock_item) = self.pinned_list.iter().find(|t| t.id == id).cloned() else { - return Task::none(); - }; - let Some(exec) = dock_item.desktop_info.exec() else { - return Task::none(); - }; - let Some(existing_popup) = self.popup.as_mut() else { - return Task::none(); - }; - - let original_name = dock_item - .desktop_info - .desktop_entry("Name") - .map(ToString::to_string) - .or_else(|| { - dock_item - .desktop_info - .name(&self.locales) - .map(Cow::into_owned) - }) - .unwrap_or_else(|| dock_item.original_app_id.clone()); - let original_exec = exec.to_string(); - let original_icon = dock_item - .desktop_info - .icon() - .unwrap_or_default() - .to_string(); - let icon_theme = cosmic::icon_theme::default(); - - self.launcher_edit = Some(LauncherEditState { - original_app_id: dock_item.original_app_id.clone(), - source_path: dock_item.desktop_info.path.clone(), - original_name: original_name.clone(), - original_exec: original_exec.clone(), - name: original_name, - exec: original_exec, - icon: original_icon.clone(), - terminal: dock_item.desktop_info.terminal(), - saving: false, - error: None, - icon_catalog: IconCatalogState { - theme: icon_theme.clone(), - query: String::new(), - entries: Vec::new(), - loading: true, - truncated: false, - }, - }); - - existing_popup.dock_item = dock_item; - existing_popup.popup_type = PopupType::LauncherEditor; - - return Task::perform( - icon_catalog::load_icon_catalog(icon_theme, original_icon), - |catalog| cosmic::Action::App(Message::LauncherIconCatalogLoaded(catalog)), - ); - } - Message::LauncherNameChanged(name) => { - if let Some(edit) = self.launcher_edit.as_mut() - && !edit.saving - { - edit.name = name; - edit.error = None; - } - } - Message::LauncherExecChanged(exec) => { - if let Some(edit) = self.launcher_edit.as_mut() - && !edit.saving - { - edit.exec = exec; - edit.error = None; - } - } - Message::LauncherIconChanged(icon) => { - if let Some(edit) = self.launcher_edit.as_mut() - && !edit.saving - { - edit.icon = icon; - edit.error = None; - } - } - Message::LauncherIconSearchChanged(query) => { - if let Some(edit) = self.launcher_edit.as_mut() { - edit.icon_catalog.query = query; - } - } - Message::LauncherIconSelected(icon) => { - if let Some(edit) = self.launcher_edit.as_mut() - && !edit.saving - { - edit.icon = icon; - edit.error = None; - } - } - Message::ReloadLauncherIconCatalog => { - if let Some(edit) = self.launcher_edit.as_mut() { - edit.icon_catalog.theme = cosmic::icon_theme::default(); - edit.icon_catalog.entries.clear(); - edit.icon_catalog.loading = true; - edit.icon_catalog.truncated = false; - - return Task::perform( - icon_catalog::load_icon_catalog( - edit.icon_catalog.theme.clone(), - edit.icon.clone(), - ), - |catalog| cosmic::Action::App(Message::LauncherIconCatalogLoaded(catalog)), - ); - } - } - Message::LauncherIconCatalogLoaded(catalog) => { - if let Some(edit) = self.launcher_edit.as_mut() - && edit.icon_catalog.theme == catalog.theme - { - edit.icon_catalog.entries = catalog.entries; - edit.icon_catalog.loading = false; - edit.icon_catalog.truncated = catalog.truncated; - } - } - Message::SaveLauncherEdit => { - let Some(edit) = self.launcher_edit.as_mut() else { - return Task::none(); - }; - if edit.saving { - return Task::none(); - } - if let Err(error) = - launcher_edit::validate_launcher_fields(&edit.name, &edit.exec, &edit.icon) - { - edit.error = Some(error); - return Task::none(); - } - - let request = LauncherEditRequest { - current_app_id: edit.original_app_id.clone(), - source_path: edit.source_path.clone(), - name: edit.name.clone(), - exec: edit.exec.clone(), - icon: edit.icon.clone(), - terminal: edit.terminal, - replace_localized_name: edit.name.trim() != edit.original_name.trim(), - disable_dbus_activation: edit.exec.trim() != edit.original_exec.trim(), - }; - - edit.saving = true; - edit.error = None; - - return Task::perform(launcher_edit::save_launcher_edit(request), |result| { - cosmic::Action::App(Message::LauncherEditSaved(result)) - }); - } - Message::CancelLauncherEdit => { - return self.close_popups(); - } - Message::LauncherEditSaved(result) => match result { - Ok(result) => { - tracing::info!( - app_id = result.new_app_id, - path = ?result.path, - "saved editable launcher" - ); - - let mut favorites = self.config.favorites.clone(); - let mut favorites_changed = false; - for favorite in &mut favorites { - if *favorite == result.old_app_id && *favorite != result.new_app_id { - *favorite = result.new_app_id.clone(); - favorites_changed = true; - } - } - - if favorites_changed { - self.config.update_pinned( - favorites.clone(), - &Config::new(APP_ID, AppListConfig::VERSION).unwrap(), - ); - self.config.favorites = favorites; - } - - self.update_desktop_entries(); - self.sync_pinned_list_from_config(); - self.launcher_edit = None; - return self.close_popups(); - } - Err(error) => { - if let Some(edit) = self.launcher_edit.as_mut() { - edit.saving = false; - edit.error = Some(error); - } - } - }, Message::Activate(handle) => { if let Some(tx) = self.wayland_sender.as_ref() { let _ = tx.send(WaylandRequest::Toplevel(ToplevelRequest::Activate(handle))); @@ -2076,9 +1520,6 @@ impl cosmic::Application for CosmicAppList { }, Message::ClosePopup => { if let Some(p) = self.popup.take() { - if p.popup_type == PopupType::LauncherEditor { - self.launcher_edit = None; - } return destroy_popup(p.id); } } @@ -2093,16 +1534,42 @@ impl cosmic::Application for CosmicAppList { } Message::ConfigUpdated(config) => { self.config = config; - self.update_desktop_entries(); - self.sync_pinned_list_from_config(); + // drain to active list + for item in self.pinned_list.drain(..) { + if !item.toplevels.is_empty() { + self.active_list.push(item); + } + } + + // pull back configured items into the favorites list + self.pinned_list = + find_desktop_entries(&self.desktop_entries, &self.config.favorites) + .zip(&self.config.favorites) + .map(|(de, original_id)| { + if let Some(p) = self + .active_list + .iter() + // match using heuristic id + .position(|dock_item| dock_item.desktop_info.id() == de.id()) + { + let mut d = self.active_list.remove(p); + // but use the id from the config + d.original_app_id.clone_from(original_id); + d + } else { + self.item_ctr += 1; + DockItem { + id: self.item_ctr, + toplevels: Vec::new(), + desktop_info: de.clone(), + original_app_id: original_id.clone(), + } + } + }) + .collect(); } Message::CloseRequested(id) => { - if let Some(popup) = &self.popup - && popup.id == id - { - if popup.popup_type == PopupType::LauncherEditor { - self.launcher_edit = None; - } + if Some(id) == self.popup.as_ref().map(|p| p.id) { self.popup = None; } if self.overflow_active_popup.is_some_and(|p| p == id) { @@ -2115,52 +1582,6 @@ impl cosmic::Application for CosmicAppList { Message::GpuRequest(gpus) => { self.gpus = gpus; } - Message::DockItemHover(id) => { - self.hovered_dock_item = id; - // Seed the animated center on the very first hover so - // the bell doesn't "fly in" from (0,0). - if self.anim_hover_center.is_none() - && let Some(hovered_id) = self.hovered_dock_item.as_ref() - && let Some(r) = self.rectangles.get(hovered_id) - { - self.anim_hover_center = Some(( - r.x + r.width / 2.0, - r.y + r.height / 2.0, - )); - } - } - Message::AnimTick(now) => { - // dt-based exponential smoothing: reach ~99% of the - // target in ~120ms at 60fps (about 7 ticks). - let dt = self - .anim_last_tick - .map(|prev| now.saturating_duration_since(prev).as_secs_f32()) - .unwrap_or(0.016) - .min(0.1); // clamp so a long pause doesn't snap - self.anim_last_tick = Some(now); - - // Intensity: target 1.0 when any icon is hovered, 0.0 else. - let intensity_target = if self.hovered_dock_item.is_some() { 1.0 } else { 0.0 }; - let tau = 0.060_f32; // time-constant (s); smaller = snappier - let alpha = 1.0 - (-dt / tau).exp(); - self.anim_hover_intensity += (intensity_target - self.anim_hover_intensity) * alpha; - - // Hovered-center smoothing: chase the real rect's center. - if let Some(hovered_id) = self.hovered_dock_item.as_ref() - && let Some(r) = self.rectangles.get(hovered_id) - { - let target = (r.x + r.width / 2.0, r.y + r.height / 2.0); - let current = self.anim_hover_center.unwrap_or(target); - self.anim_hover_center = Some(( - current.0 + (target.0 - current.0) * alpha, - current.1 + (target.1 - current.1) * alpha, - )); - } else if self.anim_hover_intensity < 0.01 { - // Nothing hovered + intensity faded out → forget the - // animated center so the next hover seeds fresh. - self.anim_hover_center = None; - } - } Message::OpenActive => { let create_new = self.overflow_active_popup.is_none(); let mut cmds = vec![self.close_popups()]; @@ -2169,63 +1590,52 @@ impl cosmic::Application for CosmicAppList { if create_new { let new_id = window::Id::unique(); self.overflow_active_popup = Some(new_id); - let Some(iced::Rectangle { + let rectangle = self.rectangles.get(&DockItemId::ActiveOverflow); + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + None, + None, + None, + ); + if let Some(iced::Rectangle { x, y, width, height, - }) = self.rectangles.get(&DockItemId::ActiveOverflow).copied() - else { - return Task::none(); + }) = rectangle + { + popup_settings.positioner.anchor_rect = iced::Rectangle:: { + x: *x as i32, + y: *y as i32, + width: *width as i32, + height: *height as i32, + }; + } + let applet_suggested_size = self.core.applet.suggested_size(false).0 + + 2 * self.core.applet.suggested_padding(false).0; + let (_favorite_popup_cutoff, active_popup_cutoff) = + self.panel_overflow_lengths(); + let popup_applet_count = + self.active_list.len().saturating_sub( + (active_popup_cutoff.unwrap_or_default()).saturating_sub(1), + ) as f32; + let popup_applet_size = applet_suggested_size as f32 * popup_applet_count + + 4.0 * (popup_applet_count - 1.); + let (max_width, max_height) = match self.core.applet.anchor { + PanelAnchor::Top | PanelAnchor::Bottom => { + (popup_applet_size, applet_suggested_size as f32) + } + PanelAnchor::Left | PanelAnchor::Right => { + (applet_suggested_size as f32, popup_applet_size) + } }; - - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - - popup_settings.positioner.anchor_rect = iced::Rectangle:: { - x: x as i32, - y: y as i32, - width: width as i32, - height: height as i32, - }; - - let applet_suggested_size = app.core.applet.suggested_size(false).0 - + 2 * app.core.applet.suggested_padding(false).0; - let (_favorite_popup_cutoff, active_popup_cutoff) = - app.panel_overflow_lengths(); - let popup_applet_count = app.active_list.len().saturating_sub( - (active_popup_cutoff.unwrap_or_default()).saturating_sub(1), - ) as f32; - let popup_applet_size = applet_suggested_size as f32 - * popup_applet_count - + 4.0 * (popup_applet_count - 1.); - let (max_width, max_height) = match app.core.applet.anchor { - PanelAnchor::Top | PanelAnchor::Bottom => { - (popup_applet_size, applet_suggested_size as f32) - } - PanelAnchor::Left | PanelAnchor::Right => { - (applet_suggested_size as f32, popup_applet_size) - } - }; - popup_settings.positioner.size_limits = Limits::NONE - .max_width(max_width) - .min_width(1.) - .max_height(max_height) - .min_height(1.); - popup_settings - }, - None, - )); - cmds.push(popup_task); + popup_settings.positioner.size_limits = Limits::NONE + .max_width(max_width) + .min_width(1.) + .max_height(max_height) + .min_height(1.); + cmds.push(get_popup(popup_settings)); } return Task::batch(cmds); } @@ -2237,63 +1647,52 @@ impl cosmic::Application for CosmicAppList { if create_new { let new_id = window::Id::unique(); self.overflow_favorites_popup = Some(new_id); - let Some(iced::Rectangle { + let rectangle = self.rectangles.get(&DockItemId::FavoritesOverflow); + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + None, + None, + None, + ); + if let Some(iced::Rectangle { x, y, width, height, - }) = self.rectangles.get(&DockItemId::FavoritesOverflow).copied() - else { - return Task::none(); + }) = rectangle + { + popup_settings.positioner.anchor_rect = iced::Rectangle:: { + x: *x as i32, + y: *y as i32, + width: *width as i32, + height: *height as i32, + }; + } + let applet_suggested_size = self.core.applet.suggested_size(false).0 + + 2 * self.core.applet.suggested_padding(false).0; + let (favorite_popup_cutoff, _active_popup_cutoff) = + self.panel_overflow_lengths(); + let popup_applet_count = + self.pinned_list.len().saturating_sub( + favorite_popup_cutoff.unwrap_or_default().saturating_sub(1), + ) as f32; + let popup_applet_size = applet_suggested_size as f32 * popup_applet_count + + 4.0 * (popup_applet_count - 1.); + let (max_width, max_height) = match self.core.applet.anchor { + PanelAnchor::Top | PanelAnchor::Bottom => { + (popup_applet_size, applet_suggested_size as f32) + } + PanelAnchor::Left | PanelAnchor::Right => { + (applet_suggested_size as f32, popup_applet_size) + } }; - - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - - popup_settings.positioner.anchor_rect = iced::Rectangle:: { - x: x as i32, - y: y as i32, - width: width as i32, - height: height as i32, - }; - - let applet_suggested_size = app.core.applet.suggested_size(false).0 - + 2 * app.core.applet.suggested_padding(false).0; - let (favorite_popup_cutoff, _active_popup_cutoff) = - app.panel_overflow_lengths(); - let popup_applet_count = app.pinned_list.len().saturating_sub( - favorite_popup_cutoff.unwrap_or_default().saturating_sub(1), - ) as f32; - let popup_applet_size = applet_suggested_size as f32 - * popup_applet_count - + 4.0 * (popup_applet_count - 1.); - let (max_width, max_height) = match app.core.applet.anchor { - PanelAnchor::Top | PanelAnchor::Bottom => { - (popup_applet_size, applet_suggested_size as f32) - } - PanelAnchor::Left | PanelAnchor::Right => { - (applet_suggested_size as f32, popup_applet_size) - } - }; - popup_settings.positioner.size_limits = Limits::NONE - .max_width(max_width) - .min_width(1.) - .max_height(max_height) - .min_height(1.); - popup_settings - }, - None, - )); - cmds.push(popup_task); + popup_settings.positioner.size_limits = Limits::NONE + .max_width(max_width) + .min_width(1.) + .max_height(max_height) + .min_height(1.); + cmds.push(get_popup(popup_settings)); } return Task::batch(cmds); } @@ -2303,7 +1702,9 @@ impl cosmic::Application for CosmicAppList { } } Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } @@ -2362,9 +1763,7 @@ impl cosmic::Application for CosmicAppList { .filter(|(info, _)| self.is_on_current_monitor_and_workspace(info)) .any(|y| focused_item.contains(&y.0.foreign_toplevel)); - let dock_id = dock_item.id; - let icon_scale = self.icon_scale_for(&DockItemId::from(dock_id)); - let tooltip = self.core + self.core .applet .applet_tooltip::( dock_item.as_icon( @@ -2377,7 +1776,6 @@ impl cosmic::Application for CosmicAppList { dot_radius, self.core.main_window_id().unwrap(), Some(&|info| self.is_on_current_monitor_and_workspace(info)), - icon_scale, ), dock_item .desktop_info @@ -2387,10 +1785,7 @@ impl cosmic::Application for CosmicAppList { self.popup.is_some(), Message::Surface, None, - ); - cosmic::widget::mouse_area(tooltip) - .on_enter(Message::DockItemHover(Some(DockItemId::from(dock_id)))) - .on_exit(Message::DockItemHover(None)) + ) .into() }) .collect(); @@ -2441,10 +1836,6 @@ impl cosmic::Application for CosmicAppList { dot_radius, self.core.main_window_id().unwrap(), Some(&|info| self.is_on_current_monitor_and_workspace(info)), - // Yoda: no magnification on DnD-preview icons — these - // float around as the user drags, so static 1.0 is - // less visually confusing. - 1.0, ), ); } else if self.is_listening_for_dnd && self.pinned_list.is_empty() { @@ -2484,10 +1875,8 @@ impl cosmic::Application for CosmicAppList { .iter() .filter(|(info, _)| self.is_on_current_monitor_and_workspace(info)) .any(|y| focused_item.contains(&y.0.foreign_toplevel)); - let dock_id = dock_item.id; - let icon_scale = self.icon_scale_for(&DockItemId::from(dock_id)); - let tooltip = self.core + self.core .applet .applet_tooltip( dock_item.as_icon( @@ -2500,7 +1889,6 @@ impl cosmic::Application for CosmicAppList { dot_radius, self.core.main_window_id().unwrap(), Some(&|info| self.is_on_current_monitor_and_workspace(info)), - icon_scale, ), dock_item .desktop_info @@ -2510,10 +1898,7 @@ impl cosmic::Application for CosmicAppList { self.popup.is_some(), Message::Surface, None, - ); - cosmic::widget::mouse_area(tooltip) - .on_enter(Message::DockItemHover(Some(DockItemId::from(dock_id)))) - .on_exit(Message::DockItemHover(None)) + ) .into() }) .collect(); @@ -2701,8 +2086,7 @@ impl cosmic::Application for CosmicAppList { .width(Length::Fill) } - let mut content = - menu::menu_column::MenuColumn::with_capacity(4).align_x(Alignment::Center); + let mut content = column![].align_x(Alignment::Center); if let Some(exec) = desktop_info.exec() { if !toplevels.is_empty() { @@ -2795,19 +2179,6 @@ impl cosmic::Application for CosmicAppList { }), ); - if is_pinned && desktop_info.exec().is_some() { - content = content.push( - menu_button( - row![ - icon::icon(from_name("edit-symbolic").into()).size(16), - text::body(fl!("edit-launcher")) - ] - .spacing(8), - ) - .on_press(Message::EditLauncher(*id)), - ); - } - if !toplevels.is_empty() { content = content.push(divider::horizontal::light()); content = match toplevels.len() { @@ -2826,6 +2197,22 @@ impl cosmic::Application for CosmicAppList { .popup_container( container(content) .padding(1) + //TODO: move style to libcosmic + .class(theme::Container::custom(|theme| { + let cosmic = theme.cosmic(); + let component = &cosmic.background.component; + container::Style { + icon_color: Some(component.on.into()), + text_color: Some(component.on.into()), + background: Some(Background::Color(component.base.into())), + border: Border { + radius: cosmic.radius_s().into(), + width: 1.0, + color: component.divider.into(), + }, + ..Default::default() + } + })) .height(Length::Shrink) .width(Length::Fill), ) @@ -2838,84 +2225,6 @@ impl cosmic::Application for CosmicAppList { ) .into() } - PopupType::LauncherEditor => { - let Some(edit) = self.launcher_edit.as_ref() else { - return text::body("").into(); - }; - - let spacing = theme::spacing(); - let can_save = !edit.saving - && launcher_edit::validate_launcher_fields( - &edit.name, &edit.exec, &edit.icon, - ) - .is_ok(); - - let mut form = column![ - text::title4(fl!("edit-launcher")), - text_input("", edit.name.as_str()) - .label(fl!("launcher-name")) - .on_input(Message::LauncherNameChanged) - .on_submit(|_| Message::SaveLauncherEdit) - .width(Length::Fill) - .size(14), - text_input("", edit.exec.as_str()) - .label(fl!("launcher-command")) - .on_input(Message::LauncherExecChanged) - .on_submit(|_| Message::SaveLauncherEdit) - .width(Length::Fill) - .size(14), - launcher_icon_editor(edit), - ] - .spacing(spacing.space_s) - .width(Length::Fill); - - if let Some(error) = edit.error.as_ref() { - form = form.push(text::caption(error.as_str()).class( - cosmic::theme::Text::Color(theme.cosmic().destructive_color().into()), - )); - } - - let cancel = - button::custom(text::body(fl!("cancel")).center().width(Length::Fill)) - .on_press_maybe(if edit.saving { - None - } else { - Some(Message::CancelLauncherEdit) - }) - .padding([spacing.space_xxs, spacing.space_s]) - .width(142); - - let save = button::custom(text::body(fl!("save")).center().width(Length::Fill)) - .class(Button::Suggested) - .on_press_maybe(if can_save { - Some(Message::SaveLauncherEdit) - } else { - None - }) - .padding([spacing.space_xxs, spacing.space_s]) - .width(142); - - let actions = row![horizontal_space(), cancel, save] - .spacing(spacing.space_xxs) - .align_y(Alignment::Center); - - let content = column![form, actions] - .spacing(spacing.space_m) - .padding(spacing.space_m) - .width(Length::Fill); - - self.core - .applet - .popup_container(container(content).width(Length::Fill)) - .limits( - Limits::NONE - .min_width(480.) - .min_height(1.) - .max_width(520.) - .max_height(1000.), - ) - .into() - } PopupType::ToplevelList => match self.core.applet.anchor { PanelAnchor::Left | PanelAnchor::Right => { let mut content = @@ -3004,10 +2313,6 @@ impl cosmic::Application for CosmicAppList { dot_radius, id, Some(&|info| self.is_on_current_monitor_and_workspace(info)), - // Yoda: icons in the overflow popup are - // already smaller-grid — keep them at 1.0 - // so the popup doesn't reshuffle on hover. - 1.0, ), dock_item .desktop_info @@ -3116,10 +2421,6 @@ impl cosmic::Application for CosmicAppList { dot_radius, id, Some(&|info| self.is_on_current_monitor_and_workspace(info)), - // Yoda: popup icons stay at 1.0 (hover - // magnification is applied to the main - // dock row only). - 1.0, ), dock_item .desktop_info @@ -3178,21 +2479,7 @@ impl cosmic::Application for CosmicAppList { } fn subscription(&self) -> Subscription { - // Yoda: ~60fps animation ticks for the fisheye magnification. - // Only emitted when an animation is actually in progress (hover - // intensity >0 OR still fading out) — keeps the panel idle when - // the pointer is nowhere near the dock. - let anim_active = self.hovered_dock_item.is_some() - || self.anim_hover_intensity > 0.001; - let anim_subscription = if anim_active { - cosmic::iced::time::every(std::time::Duration::from_millis(16)) - .map(Message::AnimTick) - } else { - Subscription::none() - }; - Subscription::batch([ - anim_subscription, wayland_subscription().map(Message::Wayland), listen_with(|e, _, id| match e { cosmic::iced::core::Event::PlatformSpecific(event::PlatformSpecific::Wayland( diff --git a/cosmic-app-list/src/icon_catalog.rs b/cosmic-app-list/src/icon_catalog.rs deleted file mode 100644 index 2cb05e1a..00000000 --- a/cosmic-app-list/src/icon_catalog.rs +++ /dev/null @@ -1,440 +0,0 @@ -use std::{ - cmp::Ordering, - collections::{HashMap, HashSet, VecDeque}, - fs, - path::{Component, Path, PathBuf}, -}; - -const FALLBACK_THEMES: &[&str] = &["Cosmic", "hicolor", "gnome", "Yaru"]; -const MAX_THEME_CHAIN: usize = 24; -const MAX_SCAN_DEPTH: usize = 5; -const MAX_CATALOG_ENTRIES: usize = 2_500; - -#[derive(Debug, Clone)] -pub struct IconCatalog { - pub theme: String, - pub entries: Vec, - pub truncated: bool, -} - -#[derive(Debug, Clone)] -pub struct IconCatalogEntry { - pub name: String, -} - -#[derive(Debug, Clone, Eq, PartialEq)] -struct CandidateRank { - preferred: u8, - category: u8, - symbolic: u8, - theme_depth: usize, - extension: u8, -} - -impl Ord for CandidateRank { - fn cmp(&self, other: &Self) -> Ordering { - ( - self.preferred, - self.category, - self.symbolic, - self.theme_depth, - self.extension, - ) - .cmp(&( - other.preferred, - other.category, - other.symbolic, - other.theme_depth, - other.extension, - )) - } -} - -impl PartialOrd for CandidateRank { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -#[derive(Debug, Clone)] -struct Candidate { - name: String, - rank: CandidateRank, -} - -pub async fn load_icon_catalog(theme: String, preferred_icon: String) -> IconCatalog { - build_icon_catalog(theme, preferred_icon) -} - -fn build_icon_catalog(theme: String, preferred_icon: String) -> IconCatalog { - let theme = if theme.trim().is_empty() { - "Cosmic".to_string() - } else { - theme - }; - let preferred_name = icon_name_from_value(preferred_icon.trim()); - let theme_chain = theme_chain(&theme); - let mut candidates = HashMap::new(); - - for (theme_depth, theme_name) in theme_chain.iter().enumerate() { - for theme_dir in theme_dirs(theme_name) { - scan_icon_tree( - &theme_dir, - theme_depth, - preferred_name.as_deref(), - &mut candidates, - ); - } - } - - for pixmap_dir in pixmap_dirs() { - scan_icon_tree( - &pixmap_dir, - theme_chain.len() + 1, - preferred_name.as_deref(), - &mut candidates, - ); - } - - let mut entries = candidates.into_values().collect::>(); - entries.sort_by(|a, b| a.rank.cmp(&b.rank).then_with(|| a.name.cmp(&b.name))); - - let truncated = entries.len() > MAX_CATALOG_ENTRIES; - entries.truncate(MAX_CATALOG_ENTRIES); - - IconCatalog { - theme, - entries: entries - .into_iter() - .map(|candidate| IconCatalogEntry { - name: candidate.name, - }) - .collect(), - truncated, - } -} - -fn theme_chain(theme: &str) -> Vec { - let mut queue = VecDeque::from([theme.to_string()]); - let mut seen = HashSet::new(); - let mut chain = Vec::new(); - - while let Some(theme_name) = queue.pop_front() { - let key = theme_name.to_ascii_lowercase(); - if !seen.insert(key) { - continue; - } - - chain.push(theme_name.clone()); - if chain.len() >= MAX_THEME_CHAIN { - break; - } - - for parent in read_theme_inherits(&theme_name) { - queue.push_back(parent); - } - } - - for fallback in FALLBACK_THEMES { - if chain.len() >= MAX_THEME_CHAIN { - break; - } - let key = fallback.to_ascii_lowercase(); - if seen.insert(key) { - chain.push((*fallback).to_string()); - } - } - - chain -} - -fn read_theme_inherits(theme: &str) -> Vec { - theme_dirs(theme) - .into_iter() - .find_map(|dir| fs::read_to_string(dir.join("index.theme")).ok()) - .map(|contents| parse_inherits(&contents)) - .unwrap_or_default() -} - -fn parse_inherits(contents: &str) -> Vec { - let mut in_icon_theme = false; - - for raw_line in contents.lines() { - let line = raw_line.trim(); - if line.is_empty() || line.starts_with('#') { - continue; - } - - if line.starts_with('[') && line.ends_with(']') { - in_icon_theme = line == "[Icon Theme]"; - continue; - } - - if in_icon_theme && let Some(value) = line.strip_prefix("Inherits=") { - return value - .split(',') - .map(str::trim) - .filter(|value| !value.is_empty()) - .map(ToOwned::to_owned) - .collect(); - } - } - - Vec::new() -} - -fn scan_icon_tree( - root: &Path, - theme_depth: usize, - preferred_name: Option<&str>, - candidates: &mut HashMap, -) { - let mut stack = vec![(root.to_path_buf(), 0usize)]; - - while let Some((dir, depth)) = stack.pop() { - if depth > MAX_SCAN_DEPTH { - continue; - } - - let Ok(entries) = fs::read_dir(&dir) else { - continue; - }; - - for entry in entries.filter_map(Result::ok) { - let path = entry.path(); - let Ok(file_type) = entry.file_type() else { - continue; - }; - - if file_type.is_dir() { - stack.push((path, depth + 1)); - } else if (file_type.is_file() || file_type.is_symlink()) - && let Some(candidate) = candidate_from_path(&path, theme_depth, preferred_name) - { - insert_candidate(candidates, candidate); - } - } - } -} - -fn insert_candidate(candidates: &mut HashMap, candidate: Candidate) { - let key = candidate.name.to_ascii_lowercase(); - match candidates.get_mut(&key) { - Some(existing) if candidate.rank < existing.rank => { - *existing = candidate; - } - None => { - candidates.insert(key, candidate); - } - _ => {} - } -} - -fn candidate_from_path( - path: &Path, - theme_depth: usize, - preferred_name: Option<&str>, -) -> Option { - let extension = extension_rank(path)?; - let name = path.file_stem()?.to_str()?.trim(); - if name.is_empty() { - return None; - } - - let symbolic = u8::from(name.ends_with("-symbolic") || path_has_component(path, "symbolic")); - let preferred = u8::from(preferred_name != Some(name)); - - Some(Candidate { - name: name.to_string(), - rank: CandidateRank { - preferred, - category: category_rank(path), - symbolic, - theme_depth, - extension, - }, - }) -} - -fn extension_rank(path: &Path) -> Option { - match path.extension()?.to_str()?.to_ascii_lowercase().as_str() { - "svg" => Some(0), - "png" => Some(1), - "xpm" => Some(2), - _ => None, - } -} - -fn category_rank(path: &Path) -> u8 { - for component in path.components().filter_map(component_str) { - match component { - "apps" | "applications" => return 0, - "categories" => return 1, - "places" => return 2, - "devices" => return 3, - "mimetypes" => return 4, - "actions" => return 5, - "status" => return 6, - _ => {} - } - } - - 7 -} - -fn path_has_component(path: &Path, needle: &str) -> bool { - path.components() - .filter_map(component_str) - .any(|component| component == needle) -} - -fn component_str(component: Component<'_>) -> Option<&str> { - component.as_os_str().to_str() -} - -fn icon_name_from_value(value: &str) -> Option { - if value.is_empty() { - return None; - } - - let path = Path::new(value); - if value.contains('/') { - return path - .file_stem() - .and_then(|name| name.to_str()) - .map(ToOwned::to_owned); - } - - path.file_stem() - .and_then(|name| name.to_str()) - .map(ToOwned::to_owned) - .or_else(|| Some(value.to_string())) -} - -fn theme_dirs(theme: &str) -> Vec { - icon_base_dirs() - .into_iter() - .map(|base| base.join(theme)) - .filter(|path| path.is_dir()) - .collect() -} - -fn icon_base_dirs() -> Vec { - let mut dirs = Vec::new(); - - if let Some(home) = std::env::home_dir() { - push_existing_unique(&mut dirs, home.join(".icons")); - } - - if let Some(data_home) = xdg_data_home() { - push_existing_unique(&mut dirs, data_home.join("icons")); - } - - for data_dir in xdg_data_dirs() { - push_existing_unique(&mut dirs, data_dir.join("icons")); - } - - dirs -} - -fn pixmap_dirs() -> Vec { - let mut dirs = Vec::new(); - - if let Some(data_home) = xdg_data_home() { - push_existing_unique(&mut dirs, data_home.join("pixmaps")); - } - - for data_dir in xdg_data_dirs() { - push_existing_unique(&mut dirs, data_dir.join("pixmaps")); - } - - push_existing_unique(&mut dirs, PathBuf::from("/usr/share/pixmaps")); - dirs -} - -fn xdg_data_home() -> Option { - std::env::var_os("XDG_DATA_HOME") - .filter(|value| !value.is_empty()) - .map(PathBuf::from) - .or_else(|| std::env::home_dir().map(|home| home.join(".local/share"))) -} - -fn xdg_data_dirs() -> Vec { - std::env::var_os("XDG_DATA_DIRS") - .filter(|value| !value.is_empty()) - .map(|value| std::env::split_paths(&value).collect()) - .unwrap_or_else(|| { - vec![ - PathBuf::from("/usr/local/share"), - PathBuf::from("/usr/share"), - ] - }) -} - -fn push_existing_unique(dirs: &mut Vec, path: PathBuf) { - if path.exists() && !dirs.iter().any(|existing| existing == &path) { - dirs.push(path); - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parses_inherits_only_from_icon_theme_section() { - let contents = r#" -[Other] -Inherits=Wrong - -[Icon Theme] -Name=Demo -Inherits=Cosmic, hicolor , Adwaita -"#; - - assert_eq!(parse_inherits(contents), ["Cosmic", "hicolor", "Adwaita"]); - } - - #[test] - fn normalizes_icon_names_from_plain_names_and_paths() { - assert_eq!(icon_name_from_value("firefox").as_deref(), Some("firefox")); - assert_eq!( - icon_name_from_value("/usr/share/icons/hicolor/scalable/apps/firefox.svg").as_deref(), - Some("firefox") - ); - } - - #[test] - fn keeps_the_best_duplicate_candidate() { - let mut candidates = HashMap::new(); - insert_candidate( - &mut candidates, - Candidate { - name: "demo".to_string(), - rank: CandidateRank { - preferred: 1, - category: 7, - symbolic: 1, - theme_depth: 4, - extension: 2, - }, - }, - ); - insert_candidate( - &mut candidates, - Candidate { - name: "demo".to_string(), - rank: CandidateRank { - preferred: 0, - category: 0, - symbolic: 0, - theme_depth: 0, - extension: 0, - }, - }, - ); - - assert_eq!(candidates["demo"].rank.preferred, 0); - assert_eq!(candidates["demo"].rank.category, 0); - } -} diff --git a/cosmic-app-list/src/launcher_edit.rs b/cosmic-app-list/src/launcher_edit.rs deleted file mode 100644 index c354e1e6..00000000 --- a/cosmic-app-list/src/launcher_edit.rs +++ /dev/null @@ -1,378 +0,0 @@ -// Copyright 2026 System76 -// SPDX-License-Identifier: GPL-3.0-only - -use std::{ - env, - ffi::OsString, - io::ErrorKind, - path::{Path, PathBuf}, -}; - -use tokio::fs; - -#[derive(Clone, Debug)] -pub struct LauncherEditRequest { - pub current_app_id: String, - pub source_path: PathBuf, - pub name: String, - pub exec: String, - pub icon: String, - pub terminal: bool, - pub replace_localized_name: bool, - pub disable_dbus_activation: bool, -} - -#[derive(Clone, Debug)] -pub struct LauncherEditResult { - pub old_app_id: String, - pub new_app_id: String, - pub path: PathBuf, -} - -#[derive(Clone, Debug)] -struct ValidLauncherEdit { - current_app_id: String, - source_path: PathBuf, - name: String, - exec: String, - icon: String, - terminal: bool, - replace_localized_name: bool, - disable_dbus_activation: bool, -} - -pub fn validate_launcher_fields(name: &str, exec: &str, icon: &str) -> Result<(), String> { - validate_required("Name", name)?; - validate_required("Command", exec)?; - validate_optional("Icon", icon)?; - Ok(()) -} - -pub async fn save_launcher_edit( - request: LauncherEditRequest, -) -> Result { - let request = validate_request(request)?; - let (new_app_id, target_path) = - target_launcher_path(&request.current_app_id, &request.source_path)?; - - let source = read_source_desktop_entry(&request).await?; - let rendered = render_editable_desktop_entry(&source, &request); - - let Some(parent) = target_path.parent() else { - return Err("Desktop file target has no parent directory".to_string()); - }; - - fs::create_dir_all(parent) - .await - .map_err(|err| format!("Could not create applications directory: {err}"))?; - - let tmp_path = temporary_path(&target_path)?; - fs::write(&tmp_path, rendered) - .await - .map_err(|err| format!("Could not write temporary desktop file: {err}"))?; - - if let Err(err) = fs::rename(&tmp_path, &target_path).await { - let _ = fs::remove_file(&tmp_path).await; - return Err(format!("Could not install desktop file: {err}")); - } - - Ok(LauncherEditResult { - old_app_id: request.current_app_id, - new_app_id, - path: target_path, - }) -} - -fn validate_request(request: LauncherEditRequest) -> Result { - let name = validate_required("Name", &request.name)?; - let exec = validate_required("Command", &request.exec)?; - let icon = validate_optional("Icon", &request.icon)?; - - Ok(ValidLauncherEdit { - current_app_id: request.current_app_id, - source_path: request.source_path, - name, - exec, - icon, - terminal: request.terminal, - replace_localized_name: request.replace_localized_name, - disable_dbus_activation: request.disable_dbus_activation, - }) -} - -fn validate_required(label: &str, value: &str) -> Result { - let value = validate_optional(label, value)?; - if value.is_empty() { - return Err(format!("{label} cannot be empty")); - } - Ok(value) -} - -fn validate_optional(label: &str, value: &str) -> Result { - if value.contains('\0') || value.contains('\n') || value.contains('\r') { - return Err(format!("{label} cannot contain line breaks")); - } - Ok(value.trim().to_string()) -} - -async fn read_source_desktop_entry(request: &ValidLauncherEdit) -> Result { - if request.source_path.as_os_str().is_empty() { - return Ok(minimal_desktop_entry()); - } - - match fs::read_to_string(&request.source_path).await { - Ok(source) => Ok(source), - Err(err) if err.kind() == ErrorKind::NotFound => Ok(minimal_desktop_entry()), - Err(err) => Err(format!("Could not read source desktop file: {err}")), - } -} - -fn minimal_desktop_entry() -> String { - "[Desktop Entry]\nType=Application\n".to_string() -} - -fn user_applications_dir() -> Result { - if let Some(xdg_data_home) = env::var_os("XDG_DATA_HOME").filter(|value| !value.is_empty()) { - return Ok(PathBuf::from(xdg_data_home).join("applications")); - } - - let Some(home) = env::var_os("HOME").filter(|value| !value.is_empty()) else { - return Err("Neither XDG_DATA_HOME nor HOME is set".to_string()); - }; - - Ok(PathBuf::from(home).join(".local/share/applications")) -} - -fn target_launcher_path(app_id: &str, source_path: &Path) -> Result<(String, PathBuf), String> { - let applications_dir = user_applications_dir()?; - if source_path.starts_with(&applications_dir) { - return Ok((app_id.to_string(), source_path.to_path_buf())); - } - - let desktop_id = normalize_desktop_id(app_id)?; - Ok(( - desktop_id.clone(), - applications_dir.join(format!("{desktop_id}.desktop")), - )) -} - -fn normalize_desktop_id(app_id: &str) -> Result { - if app_id.contains('\0') || app_id.contains('\n') || app_id.contains('\r') { - return Err("Desktop ID cannot contain line breaks".to_string()); - } - - let desktop_id = app_id - .chars() - .map(|c| if c == '/' { '-' } else { c }) - .collect::(); - - if desktop_id.trim().is_empty() { - return Err("Desktop ID cannot be empty".to_string()); - } - - Ok(desktop_id) -} - -fn temporary_path(target_path: &Path) -> Result { - let Some(file_name) = target_path.file_name() else { - return Err("Desktop file target has no filename".to_string()); - }; - - let mut tmp_file_name = OsString::from("."); - tmp_file_name.push(file_name); - tmp_file_name.push(format!(".tmp-{}", std::process::id())); - - Ok(target_path.with_file_name(tmp_file_name)) -} - -fn render_editable_desktop_entry(source: &str, request: &ValidLauncherEdit) -> String { - let mut updates = vec![ - ("Type", "Application".to_string()), - ("Name", request.name.clone()), - ("Exec", request.exec.clone()), - ("Icon", request.icon.clone()), - ( - "Terminal", - if request.terminal { "true" } else { "false" }.to_string(), - ), - ("X-COSMIC-UserEditable", "true".to_string()), - ("X-COSMIC-SourceDesktopId", request.current_app_id.clone()), - ]; - - if !request.source_path.as_os_str().is_empty() { - updates.push(( - "X-COSMIC-SourceDesktopPath", - request.source_path.to_string_lossy().to_string(), - )); - } - - if request.disable_dbus_activation { - updates.push(("DBusActivatable", "false".to_string())); - } - - set_desktop_entry_keys( - source, - &updates, - request.replace_localized_name, - request.disable_dbus_activation, - ) -} - -fn set_desktop_entry_keys( - source: &str, - updates: &[(&str, String)], - replace_localized_name: bool, - remove_try_exec: bool, -) -> String { - let mut out = Vec::new(); - let mut seen = vec![false; updates.len()]; - let mut in_desktop_entry = false; - let mut saw_desktop_entry = false; - - for line in source.lines() { - if let Some(section) = section_name(line) { - if in_desktop_entry { - insert_missing_keys(&mut out, updates, &seen); - } - - in_desktop_entry = section == "Desktop Entry"; - saw_desktop_entry |= in_desktop_entry; - if in_desktop_entry { - seen.fill(false); - } - - out.push(line.to_string()); - continue; - } - - if in_desktop_entry && let Some(key) = desktop_entry_key(line) { - if replace_localized_name && key.starts_with("Name[") { - continue; - } - - if remove_try_exec && key == "TryExec" { - continue; - } - - if let Some(index) = updates - .iter() - .position(|(update_key, _)| *update_key == key) - { - out.push(format!("{}={}", updates[index].0, updates[index].1)); - seen[index] = true; - continue; - } - } - - out.push(line.to_string()); - } - - if in_desktop_entry { - insert_missing_keys(&mut out, updates, &seen); - } - - if !saw_desktop_entry { - let mut with_desktop_entry = Vec::with_capacity(out.len() + updates.len() + 2); - with_desktop_entry.push("[Desktop Entry]".to_string()); - insert_missing_keys( - &mut with_desktop_entry, - updates, - &vec![false; updates.len()], - ); - if !out.is_empty() { - with_desktop_entry.push(String::new()); - with_desktop_entry.extend(out); - } - out = with_desktop_entry; - } - - let mut rendered = out.join("\n"); - rendered.push('\n'); - rendered -} - -fn insert_missing_keys(out: &mut Vec, updates: &[(&str, String)], seen: &[bool]) { - for (index, (key, value)) in updates.iter().enumerate() { - if !seen[index] { - out.push(format!("{key}={value}")); - } - } -} - -fn section_name(line: &str) -> Option<&str> { - let trimmed = line.trim(); - trimmed - .strip_prefix('[') - .and_then(|value| value.strip_suffix(']')) -} - -fn desktop_entry_key(line: &str) -> Option<&str> { - let line = line.trim_start(); - if line.starts_with('#') || line.starts_with(';') { - return None; - } - - line.split_once('=').map(|(key, _)| key.trim_end()) -} - -#[cfg(test)] -mod tests { - use super::*; - - fn request() -> ValidLauncherEdit { - ValidLauncherEdit { - current_app_id: "org.example.App".to_string(), - source_path: PathBuf::from("/usr/share/applications/org.example.App.desktop"), - name: "Example".to_string(), - exec: "example --new".to_string(), - icon: "example-custom".to_string(), - terminal: false, - replace_localized_name: true, - disable_dbus_activation: true, - } - } - - #[test] - fn updates_desktop_entry_without_dropping_action_groups() { - let source = "\ -[Desktop Entry] -Type=Application -Name=Old -Name[fr]=Ancien -Exec=old -TryExec=old -Icon=old -DBusActivatable=true -Actions=new-window; - -[Desktop Action new-window] -Name=New Window -Exec=old --new-window -"; - - let rendered = render_editable_desktop_entry(source, &request()); - - assert!(rendered.contains("Name=Example\n")); - assert!(!rendered.contains("Name[fr]=")); - assert!(rendered.contains("Exec=example --new\n")); - assert!(rendered.contains("Icon=example-custom\n")); - assert!(rendered.contains("DBusActivatable=false\n")); - assert!(!rendered.contains("TryExec=")); - assert!(rendered.contains("[Desktop Action new-window]\n")); - assert!(rendered.contains("Exec=old --new-window\n")); - } - - #[test] - fn preserves_localized_names_when_name_is_unchanged() { - let mut edit = request(); - edit.replace_localized_name = false; - - let rendered = render_editable_desktop_entry( - "[Desktop Entry]\nName=Example\nName[fr]=Exemple\nExec=old\n", - &edit, - ); - - assert!(rendered.contains("Name=Example\n")); - assert!(rendered.contains("Name[fr]=Exemple\n")); - } -} diff --git a/cosmic-app-list/src/lib.rs b/cosmic-app-list/src/lib.rs index f6893335..51079cc4 100644 --- a/cosmic-app-list/src/lib.rs +++ b/cosmic-app-list/src/lib.rs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only mod app; -mod icon_catalog; -mod launcher_edit; mod localize; mod wayland_handler; mod wayland_subscription; diff --git a/cosmic-app-list/src/wayland_handler.rs b/cosmic-app-list/src/wayland_handler.rs index d27409dc..03c16973 100644 --- a/cosmic-app-list/src/wayland_handler.rs +++ b/cosmic-app-list/src/wayland_handler.rs @@ -388,10 +388,7 @@ impl CaptureData { }, ) .unwrap(); - if let Err(err) = self.conn.flush() { - tracing::error!("Wayland flush failed during screencopy session create: {err}"); - return None; - } + self.conn.flush().unwrap(); let formats = session .wait_while(|data| data.formats.is_none()) @@ -440,10 +437,7 @@ impl CaptureData { session: capture_session.clone(), }, ); - if let Err(err) = self.conn.flush() { - tracing::error!("Wayland flush failed during screencopy capture: {err}"); - return None; - } + self.conn.flush().unwrap(); // TODO: wait for server to release buffer? let res = session @@ -715,10 +709,7 @@ pub(crate) fn wayland_handler( if app_data.exit { break; } - if let Err(err) = event_loop.dispatch(None, &mut app_data) { - tracing::error!("Wayland event loop terminated: {err}"); - break; - } + event_loop.dispatch(None, &mut app_data).unwrap(); } } diff --git a/cosmic-applet-a11y/Cargo.toml b/cosmic-applet-a11y/Cargo.toml index ee1f52ba..a5bb12b4 100644 --- a/cosmic-applet-a11y/Cargo.toml +++ b/cosmic-applet-a11y/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-a11y" -version = "1.9.0" +version = "1.0.2" edition = "2024" [dependencies] @@ -9,7 +9,7 @@ cctk.workspace = true cosmic-protocols.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true +libcosmic.workspace = true rust-embed.workspace = true tokio.workspace = true tracing-log.workspace = true @@ -17,7 +17,9 @@ tracing-subscriber.workspace = true tracing.workspace = true [dependencies.cosmic-settings-a11y-manager-subscription] -path = "../../cosmic-settings/subscriptions/a11y-manager" +git = "https://github.com/pop-os/cosmic-settings" +# path = "../../cosmic-settings/subscriptions/a11y-manager" [dependencies.cosmic-settings-accessibility-subscription] -path = "../../cosmic-settings/subscriptions/accessibility" +git = "https://github.com/pop-os/cosmic-settings" +# path = "../../cosmic-settings/subscriptions/accessibility" diff --git a/cosmic-applet-a11y/i18n/ca/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/ca/cosmic_applet_a11y.ftl index 25383cbe..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/ca/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/ca/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -magnifier = Lupa -screen-reader = Narrador -invert-colors = Colors invertits -settings = Configuració d'accessibilitat... -filter-colors = Filtres de colors -high-contrast = Mode d'alt contrast diff --git a/cosmic-applet-a11y/i18n/cs/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/cs/cosmic_applet_a11y.ftl index e8ca4a2a..ed88c73e 100644 --- a/cosmic-applet-a11y/i18n/cs/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/cs/cosmic_applet_a11y.ftl @@ -1,6 +1,6 @@ screen-reader = Čtečka obrazovky magnifier = Lupa -invert-colors = Inverze barev +invert-colors = Převrátit barvy settings = Nastavení přístupnosti... -filter-colors = Filtr barev +filter-colors = Filtrovat barvy high-contrast = Vysoký kontrast diff --git a/cosmic-applet-a11y/i18n/da/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/da/cosmic_applet_a11y.ftl index 85729331..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/da/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/da/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -screen-reader = Skærmlæser -invert-colors = Invertér farver -high-contrast = Høj kontrast -filter-colors = Filtrér farver -settings = Tilgængelighedsindstillinger... -magnifier = Forstørrelsesglas diff --git a/cosmic-applet-a11y/i18n/de/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/de/cosmic_applet_a11y.ftl index 0a5413a5..84e24922 100644 --- a/cosmic-applet-a11y/i18n/de/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/de/cosmic_applet_a11y.ftl @@ -1,6 +1,6 @@ screen-reader = Bildschirmleser magnifier = Vergrößerungsglas invert-colors = Farben invertieren -settings = Barrierefreiheitseinstellungen ... +settings = Barrierefreiheitseinstellungen… filter-colors = Farben filtern high-contrast = Hoher Kontrast diff --git a/cosmic-applet-a11y/i18n/el/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/el/cosmic_applet_a11y.ftl index 609965b5..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/el/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/el/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -screen-reader = Ανάγνωση οθόνης -invert-colors = Αναστροφή χρωμάτων -high-contrast = Υψηλή αντίθεση -settings = Ρυθμίσεις προσβασιμότητας... -magnifier = Μεγεθυντικός φακός -filter-colors = Φίλτρο χρωμάτων diff --git a/cosmic-applet-a11y/i18n/en-GB/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/en-GB/cosmic_applet_a11y.ftl index b504adf2..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/en-GB/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/en-GB/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -screen-reader = Screen reader -invert-colors = Invert colours -high-contrast = High contrast -filter-colors = Filter colours -settings = Accessibility settings... -magnifier = Magnifier diff --git a/cosmic-applet-a11y/i18n/fa/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/fa/cosmic_applet_a11y.ftl index 66820364..e43e3a1d 100644 --- a/cosmic-applet-a11y/i18n/fa/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/fa/cosmic_applet_a11y.ftl @@ -1,6 +1,6 @@ screen-reader = صفحه‌خوان magnifier = ذره‌بین -invert-colors = وارونه کردن رنگ‌ها +invert-colors = وارونه‌سازی رنگ‌ها settings = تنظیمات دسترسی‌پذیری... filter-colors = فیلتر رنگ‌ها high-contrast = کنتراست بالا diff --git a/cosmic-applet-a11y/i18n/fil/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/fil/cosmic_applet_a11y.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-a11y/i18n/gl/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/gl/cosmic_applet_a11y.ftl deleted file mode 100644 index d0da1ab5..00000000 --- a/cosmic-applet-a11y/i18n/gl/cosmic_applet_a11y.ftl +++ /dev/null @@ -1,6 +0,0 @@ -screen-reader = Lector de pantalla -magnifier = Lupa -invert-colors = Invertir cores -settings = Configuración de accesibilidade... -filter-colors = Filtro de cores -high-contrast = Alto contraste diff --git a/cosmic-applet-a11y/i18n/hi/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/hi/cosmic_applet_a11y.ftl index 97aace4d..a43e2110 100644 --- a/cosmic-applet-a11y/i18n/hi/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/hi/cosmic_applet_a11y.ftl @@ -1,6 +1,4 @@ screen-reader = स्क्रीन रीडर -filter-colors = रंग फ़िल्टर करें -settings = एक्सेसिबिलिटी सेटिंग्स..। -magnifier = मैग्नीफायर -high-contrast = उच्च कंट्रास्ट -invert-colors = रंग उल्टे करें +filter-colors = रंग फ़िल्टर +settings = सुलभता सेटिंग..। +magnifier = आवर्धक diff --git a/cosmic-applet-a11y/i18n/it/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/it/cosmic_applet_a11y.ftl index 11e6a115..2902795c 100644 --- a/cosmic-applet-a11y/i18n/it/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/it/cosmic_applet_a11y.ftl @@ -2,5 +2,5 @@ screen-reader = Lettore dello schermo magnifier = Lente di ingrandimento invert-colors = Inverti colori settings = Impostazioni accessibilità... -filter-colors = Filtri colore +filter-colors = Filtra colori high-contrast = Contrasto elevato diff --git a/cosmic-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl index 564e0d4f..75249579 100644 --- a/cosmic-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl @@ -2,5 +2,5 @@ screen-reader = スクリーンリーダー magnifier = 拡大鏡 settings = アクセシビリティ設定… invert-colors = 色を反転 -filter-colors = カラーフィルター +filter-colors = 色のフィルター high-contrast = ハイコントラスト diff --git a/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl index 4c772791..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -screen-reader = Xwînerê dîmenderê -magnifier = Mezinker -invert-colors = Rengan berevajî bike -settings = Sazkariyên gihîştinê... -filter-colors = Rengan parzûn bike -high-contrast = Dijbiriya bilind diff --git a/cosmic-applet-a11y/i18n/lo/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/lo/cosmic_applet_a11y.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-a11y/i18n/sat/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/sat/cosmic_applet_a11y.ftl deleted file mode 100644 index 8c46d41c..00000000 --- a/cosmic-applet-a11y/i18n/sat/cosmic_applet_a11y.ftl +++ /dev/null @@ -1,2 +0,0 @@ -screen-reader = ᱥᱠᱨᱤᱱ ᱨᱤᱰᱟᱨ -invert-colors = ᱨᱚᱝ ᱩᱞᱴᱟᱹ ᱪᱷᱚ diff --git a/cosmic-applet-a11y/i18n/sr/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/sr/cosmic_applet_a11y.ftl index 76d163eb..e69de29b 100644 --- a/cosmic-applet-a11y/i18n/sr/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/sr/cosmic_applet_a11y.ftl @@ -1,6 +0,0 @@ -screen-reader = Читач екрана -invert-colors = Обрни боје -high-contrast = Високи контраст -filter-colors = Филтрирај боје -settings = Подешавања приступачности... -magnifier = Увеличавач diff --git a/cosmic-applet-a11y/src/app.rs b/cosmic-applet-a11y/src/app.rs index 7039f447..ad5f2a1e 100644 --- a/cosmic-applet-a11y/src/app.rs +++ b/cosmic-applet-a11y/src/app.rs @@ -26,9 +26,10 @@ use cosmic::{ }; use cosmic_settings_a11y_manager_subscription::{ - AccessibilityEvent, AccessibilityRequest, ColorFilter, + self as cosmic_a11y_manager, AccessibilityEvent, AccessibilityRequest, ColorFilter, }; use cosmic_settings_accessibility_subscription::{self as accessibility}; +use std::sync::LazyLock; use tokio::sync::mpsc::UnboundedSender; pub fn run() -> cosmic::iced::Result { @@ -51,7 +52,6 @@ struct CosmicA11yApplet { } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), @@ -64,7 +64,7 @@ enum Message { OpenSettings, DBusUpdate(accessibility::Response), WaylandUpdate(WaylandUpdate), - Surface(surface::Action), + Surface(surface::Action), } impl cosmic::Application for CosmicA11yApplet { @@ -133,27 +133,20 @@ impl cosmic::Application for CosmicA11yApplet { } Message::TogglePopup => { if let Some(p) = self.popup.take() { - return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup( - p, - )); + return destroy_popup(p); } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut CosmicA11yApplet| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); + let new_id = window::Id::unique(); + self.popup.replace(new_id); - let popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - Some((1, 1)), - None, - None, - ); - popup_settings - }, + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + Some((1, 1)), None, - )); + None, + ); + + return get_popup(popup_settings); } } Message::CloseRequested(id) => { @@ -288,7 +281,9 @@ impl cosmic::Application for CosmicA11yApplet { } }, Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } Task::none() diff --git a/cosmic-applet-a11y/src/backend/wayland/mod.rs b/cosmic-applet-a11y/src/backend/wayland/mod.rs index 12340588..fa9796f0 100644 --- a/cosmic-applet-a11y/src/backend/wayland/mod.rs +++ b/cosmic-applet-a11y/src/backend/wayland/mod.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: GPL-3.0-only use anyhow; -use cctk::sctk::reexports::calloop::{self}; +use cctk::sctk::reexports::calloop::{self, channel::SyncSender}; use cosmic::iced::{ self, Subscription, - futures::{self, SinkExt}, + futures::{self, SinkExt, StreamExt, channel::mpsc}, stream, }; +use cosmic_protocols::a11y::v1::client::cosmic_a11y_manager_v1::Filter; use cosmic_settings_a11y_manager_subscription::{ self as thread, AccessibilityEvent, AccessibilityRequest, }; diff --git a/cosmic-applet-audio/Cargo.toml b/cosmic-applet-audio/Cargo.toml index 0764fe49..96d37cad 100644 --- a/cosmic-applet-audio/Cargo.toml +++ b/cosmic-applet-audio/Cargo.toml @@ -1,15 +1,15 @@ [package] name = "cosmic-applet-audio" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] -futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true -mpris2-zbus = { path = "../../dbus-settings-bindings/mpris2" } +libcosmic.workspace = true +mpris2-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } +# mpris2-zbus = { path = "../../dbus-settings-bindings/mpris2" } rust-embed.workspace = true serde.workspace = true tokio.workspace = true @@ -19,9 +19,7 @@ tracing.workspace = true url = "2" urlencoding = "2.1.3" zbus.workspace = true -zlink.workspace = true -intmap = "3.1.3" -[dependencies.cosmic-settings-audio-client] -path = "../../cosmic-settings-daemon/audio-client" -features = ["codec"] +[dependencies.cosmic-settings-sound-subscription] +git = "https://github.com/pop-os/cosmic-settings" +# path = "../../cosmic-settings/subscriptions/sound" diff --git a/cosmic-applet-audio/i18n/ca/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/ca/cosmic_applet_audio.ftl index 0bbe1d5f..e69de29b 100644 --- a/cosmic-applet-audio/i18n/ca/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/ca/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -output = Sortida -show-media-controls = Mostra els controls multimèdia a la barra -disconnected = PulseAudio desconnectat -no-device = No s'ha seleccionat cap dispositiu -input = Entrada -unknown-artist = Desconegut -sound-settings = Configuració de so... diff --git a/cosmic-applet-audio/i18n/da/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/da/cosmic_applet_audio.ftl index 7cdb3d06..e69de29b 100644 --- a/cosmic-applet-audio/i18n/da/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/da/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -show-media-controls = Vis mediekontrol på panel -disconnected = PulseAudio Afbrudt -no-device = Ingen enhed valgt -input = Indgang -output = Udgang -unknown-artist = Ukendt -sound-settings = Lydindstillinger... diff --git a/cosmic-applet-audio/i18n/de/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/de/cosmic_applet_audio.ftl index 1b535907..a0128f53 100644 --- a/cosmic-applet-audio/i18n/de/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/de/cosmic_applet_audio.ftl @@ -1,7 +1,7 @@ output = Ausgabe input = Eingabe show-media-controls = Mediensteuerung im Panel anzeigen -sound-settings = Klang-Einstellungen ... +sound-settings = Klang-Einstellungen... disconnected = PulseAudio getrennt no-device = Kein Gerät ausgewählt unknown-artist = Unbekannt diff --git a/cosmic-applet-audio/i18n/el/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/el/cosmic_applet_audio.ftl index 1bdfccf1..e69de29b 100644 --- a/cosmic-applet-audio/i18n/el/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/el/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -output = Έξοδος -show-media-controls = Εμφάνιση στοιχείων ελέγχου πολυμέσων στη γραμμή συστήματος -disconnected = Το PulseAudio αποσυνδέθηκε -no-device = Καμία επιλεγμένη συσκευή -input = Είσοδος -unknown-artist = Άγνωστος -sound-settings = Ρυθμίσεις ήχου... diff --git a/cosmic-applet-audio/i18n/en-GB/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/en-GB/cosmic_applet_audio.ftl index cb19412d..e69de29b 100644 --- a/cosmic-applet-audio/i18n/en-GB/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/en-GB/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -show-media-controls = Show media controls on panel -disconnected = PulseAudio Disconnected -no-device = No device selected -input = Input -output = Output -unknown-artist = Unknown -sound-settings = Sound Settings... diff --git a/cosmic-applet-audio/i18n/fil/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/fil/cosmic_applet_audio.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-audio/i18n/gl/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/gl/cosmic_applet_audio.ftl deleted file mode 100644 index c0a90f1e..00000000 --- a/cosmic-applet-audio/i18n/gl/cosmic_applet_audio.ftl +++ /dev/null @@ -1,7 +0,0 @@ -output = Saída -input = Entrada -show-media-controls = Mostrar os controis multimedia no panel -sound-settings = Axustes do son... -disconnected = PulseAudio Desconectado -no-device = Ningún dipositivo seleccionado -unknown-artist = Descoñecido diff --git a/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl index b3fdb11d..c26f9fb0 100644 --- a/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl @@ -2,6 +2,6 @@ output = Kimenet input = Bemenet show-media-controls = Médiavezérlők megjelenítése a panelen sound-settings = Hangbeállítások… -disconnected = A PulseAudio-kapcsolat megszakadt -no-device = Nincs eszköz kiválasztva +disconnected = PulseAudio nincs csatlakozva +no-device = Nincs kiválasztott eszköz unknown-artist = Ismeretlen diff --git a/cosmic-applet-audio/i18n/it/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/it/cosmic_applet_audio.ftl index 46f61b33..f48e0ac2 100644 --- a/cosmic-applet-audio/i18n/it/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/it/cosmic_applet_audio.ftl @@ -4,4 +4,4 @@ show-media-controls = Mostra controlli multimediali nel pannello in alto sound-settings = Impostazioni audio... disconnected = PulseAudio Disconnesso no-device = Nessun dispositivo selezionato -unknown-artist = Sconosciuto +unknown-artist = Sconosciuto \ No newline at end of file diff --git a/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl index 373ab157..e69de29b 100644 --- a/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -output = Deran -input = Ketan -unknown-artist = Nenas -sound-settings = Sazkariyên dengê... -disconnected = Girêdana PulseAudio qut bû -no-device = Tu amûr nehatine hilbijartin -show-media-controls = Kontrolên mediyayê li ser destgehê nîşan bide diff --git a/cosmic-applet-audio/i18n/lo/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/lo/cosmic_applet_audio.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-audio/i18n/lt/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/lt/cosmic_applet_audio.ftl index 3152f388..4e96ec80 100644 --- a/cosmic-applet-audio/i18n/lt/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/lt/cosmic_applet_audio.ftl @@ -4,4 +4,4 @@ no-device = Nepasirinktas įrenginys input = Įvestis output = Išvestis unknown-artist = Nežinomas atlikėjas -sound-settings = Garso Nuostatos... +sound-settings = Garso Nustatymai... diff --git a/cosmic-applet-audio/i18n/oc/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/oc/cosmic_applet_audio.ftl index 87d44967..e69de29b 100644 --- a/cosmic-applet-audio/i18n/oc/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/oc/cosmic_applet_audio.ftl @@ -1 +0,0 @@ -output = Sortida diff --git a/cosmic-applet-audio/i18n/sat/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/sat/cosmic_applet_audio.ftl deleted file mode 100644 index b248256d..00000000 --- a/cosmic-applet-audio/i18n/sat/cosmic_applet_audio.ftl +++ /dev/null @@ -1 +0,0 @@ -output = ᱟᱨᱡᱟᱣ diff --git a/cosmic-applet-audio/i18n/sr/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/sr/cosmic_applet_audio.ftl index 9ddf8185..e69de29b 100644 --- a/cosmic-applet-audio/i18n/sr/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/sr/cosmic_applet_audio.ftl @@ -1,7 +0,0 @@ -show-media-controls = Прикажи управљања медијима на траци -disconnected = Пулс-аудио откачен -no-device = Ниједан уређај није изабран -input = Улаз -output = Излаз -unknown-artist = Непознато -sound-settings = Подешавања звука... diff --git a/cosmic-applet-audio/src/lib.rs b/cosmic-applet-audio/src/lib.rs index 60607016..5f49d0f9 100644 --- a/cosmic-applet-audio/src/lib.rs +++ b/cosmic-applet-audio/src/lib.rs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only mod localize; -mod model; mod mouse_area; use crate::localize::localize; use config::{AudioAppletConfig, amplification_sink, amplification_source}; use cosmic::{ - Apply, Element, Renderer, Task, Theme, app, + Element, Renderer, Task, Theme, app, applet::{ column as applet_column, cosmic_panel_config::PanelAnchor, @@ -19,29 +18,18 @@ use cosmic::{ cosmic_config::CosmicConfigEntry, cosmic_theme::Spacing, iced::{ - self, Alignment, Length, Rectangle, Subscription, + self, Alignment, Length, Subscription, futures::StreamExt, widget::{self, column, row, slider}, window, }, surface, theme, - widget::{ - Row, button, container, divider, icon, - rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, - space, text, toggler, - }, + widget::{Row, button, container, divider, icon, space, text, toggler}, }; -use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy}; -use futures::SinkExt; +use cosmic_settings_sound_subscription as css; +use iced::platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup}; use mpris_subscription::{MprisRequest, MprisUpdate}; use mpris2_zbus::player::PlaybackStatus; -use std::{ - sync::{ - Arc, - atomic::{self, AtomicU32}, - }, - time::Duration, -}; mod config; mod mpris_subscription; @@ -62,16 +50,10 @@ pub struct Audio { core: cosmic::app::Core, /// Track the applet's popup window. popup: Option, - /// Varlink connection to `com.system76.CosmicSettings.Audio`. - audio_client: Option, - /// Known audio device state - model: model::Model, + /// The model from cosmic-settings for managing pipewire devices. + model: css::Model, /// Whether to expand the revealer of a source or sink device. is_open: IsOpen, - /// Used to debounce sink volume updates. - applied_sink_volume: Arc, - /// Used to deboune source volume updates. - applied_source_volume: Arc, /// Max slider volume for the sink device, as determined by the amplification property. max_sink_volume: u32, /// Max slider volume for the source device, as determined by the amplification property. @@ -86,14 +68,12 @@ pub struct Audio { player_status: Option, /// Used to request an activation token for opening cosmic-settings. token_tx: Option>, - rectangle_tracker: Option>, - rectangle: Option, } impl Audio { fn output_icon_name(&self) -> &'static str { - let volume = self.model.active_sink.volume; - let mute = self.model.active_sink.mute; + let volume = self.model.sink_volume; + let mute = self.model.sink_mute; if mute || volume == 0 { "audio-volume-muted-symbolic" } else if volume < 33 { @@ -108,8 +88,8 @@ impl Audio { } fn input_icon_name(&self) -> &'static str { - let volume = self.model.active_source.volume; - let mute = self.model.active_source.mute; + let volume = self.model.source_volume; + let mute = self.model.source_mute; if mute || volume == 0 { "microphone-sensitivity-muted-symbolic" } else if volume < 33 { @@ -120,21 +100,6 @@ impl Audio { "microphone-sensitivity-high-symbolic" } } - - /// Refresh the volume ceilings and slider breakpoints from the - /// amplification config. - /// - /// Must run at startup, not only when the popup opens: the - /// scroll-to-adjust handler clamps against `max_sink_volume`, which - /// `Default` leaves at 0. Until the popup had been opened once, every - /// wheel event therefore resolved to `SetSinkVolume(0)`. - fn refresh_volume_limits(&mut self) { - (self.max_sink_volume, self.sink_breakpoints) = - if amplification_sink() { (150, &[100][..]) } else { (100, &[][..]) }; - - (self.max_source_volume, self.source_breakpoints) = - if amplification_source() { (150, &[100][..]) } else { (100, &[][..]) }; - } } #[derive(Debug, PartialEq, Eq, Default)] @@ -145,31 +110,27 @@ enum IsOpen { Input, } -#[derive(Clone, Debug)] +#[derive(Debug, Clone)] pub enum Message { - /// Connection to `com.system76.CosmicSettings`. - Client(Arc), - CloseRequested(window::Id), - ConfigChanged(AudioAppletConfig), Ignore, - InputToggle, - Mpris(mpris_subscription::MprisUpdate), - MprisRequest(MprisRequest), - OpenSettings, - OutputToggle, - ReattachClient(Arc), - Rectangle(RectangleUpdate), - SetDefaultSink(usize), - SetDefaultSource(usize), SetSinkVolume(u32), SetSourceVolume(u32), - Subscription(audio_client::Event), - Surface(surface::Action), - ToggleMediaControlsInTopPanel(bool), - TogglePopup, ToggleSinkMute, ToggleSourceMute, + SetDefaultSink(usize), + SetDefaultSource(usize), + OutputToggle, + InputToggle, + TogglePopup, + CloseRequested(window::Id), + ToggleMediaControlsInTopPanel(bool), + ConfigChanged(AudioAppletConfig), + Mpris(mpris_subscription::MprisUpdate), + MprisRequest(MprisRequest), Token(TokenUpdate), + OpenSettings, + Subscription(css::Message), + Surface(surface::Action), } // TODO @@ -281,13 +242,19 @@ impl cosmic::Application for Audio { const APP_ID: &'static str = "com.system76.CosmicAppletAudio"; fn init(core: cosmic::app::Core, _flags: ()) -> (Self, app::Task) { - let mut app = Self { - core, - ..Default::default() - }; - app.refresh_volume_limits(); + let mut model = css::Model::default(); + model.unplugged_text = "Unplugged".into(); + model.hd_audio_text = "HD Audio".into(); + model.usb_audio_text = "USB Audio".into(); - (app, Task::none()) + ( + Self { + core, + model, + ..Default::default() + }, + Task::none(), + ) } fn core(&self) -> &cosmic::app::Core { @@ -304,53 +271,35 @@ impl cosmic::Application for Audio { fn update(&mut self, message: Message) -> app::Task { match message { - Message::Rectangle(u) => match u { - RectangleUpdate::Rectangle(r) => { - self.rectangle = Some(r.1); - } - RectangleUpdate::Init(tracker) => { - self.rectangle_tracker.replace(tracker); - } - }, - Message::ReattachClient(client) => { - if let Some(client) = Arc::into_inner(client) { - self.audio_client = Some(client); - } - } Message::Ignore => {} Message::TogglePopup => { if let Some(p) = self.popup.take() { - return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup( - p, - )); + return destroy_popup(p); } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); + let new_id = window::Id::unique(); + self.popup.replace(new_id); - app.refresh_volume_limits(); + (self.max_sink_volume, self.sink_breakpoints) = if amplification_sink() { + (150, &[100][..]) + } else { + (100, &[][..]) + }; - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - if let Some(r) = app.rectangle { - popup_settings.positioner.anchor_rect = Rectangle { - x: r.x as i32, - y: r.y as i32, - width: r.width as i32, - height: r.height as i32, - }; - } - popup_settings - }, + (self.max_source_volume, self.source_breakpoints) = if amplification_source() { + (150, &[100][..]) + } else { + (100, &[][..]) + }; + + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, None, - )); + None, + None, + ); + + return get_popup(popup_settings); } } @@ -369,90 +318,52 @@ impl cosmic::Application for Audio { } } Message::Subscription(message) => { - self.model.update(message); + return self + .model + .update(message) + .map(|message| Message::Subscription(message).into()); } Message::SetDefaultSink(pos) => { - if let Some(&pos) = self.model.sinks.sorted_index.get(pos) - && let Some(&node_id) = self.model.sinks.id.get(pos as usize) - && let Some(client) = self.audio_client.as_mut() - { - futures::executor::block_on(async { - _ = client.conn.set_default(node_id, true).await; - }); - } + return self + .model + .set_default_sink(pos) + .map(|message| Message::Subscription(message).into()); } Message::SetDefaultSource(pos) => { - if let Some(&pos) = self.model.sources.sorted_index.get(pos) - && let Some(&node_id) = self.model.sources.id.get(pos as usize) - && let Some(client) = self.audio_client.as_mut() - { - futures::executor::block_on(async { - _ = client.conn.set_default(node_id, true).await; - }); - } + return self + .model + .set_default_source(pos) + .map(|message| Message::Subscription(message).into()); } - Message::ToggleSinkMute => { - if let Some(ref mut client) = self.audio_client { - futures::executor::block_on(async { - _ = client.conn.sink_mute_toggle().await; - }); - } - } + Message::ToggleSinkMute => self.model.toggle_sink_mute(), - Message::ToggleSourceMute => { - if let Some(ref mut client) = self.audio_client { - futures::executor::block_on(async { - _ = client.conn.source_mute_toggle().await; - }); - } - } + Message::ToggleSourceMute => self.model.toggle_source_mute(), Message::SetSinkVolume(volume) => { - self.applied_sink_volume - .store(volume, atomic::Ordering::Relaxed); - self.model.active_sink.volume = volume; - self.model.active_sink.volume_text = volume.to_string(); - if let Some(mut client) = self.audio_client.take() { - let volume = Arc::clone(&self.applied_sink_volume); - return cosmic::Task::future(async move { - tokio::time::sleep(Duration::from_millis(128)).await; - _ = client - .conn - .set_sink_volume(volume.load(atomic::Ordering::Relaxed)) - .await; - Message::ReattachClient(Arc::new(client)).into() - }); - } + return self + .model + .set_sink_volume(volume) + .map(|message| Message::Subscription(message).into()); } Message::SetSourceVolume(volume) => { - self.applied_source_volume - .store(volume, atomic::Ordering::Relaxed); - self.model.active_source.volume = volume; - self.model.active_source.volume_text = volume.to_string(); - if let Some(mut client) = self.audio_client.take() { - let volume = Arc::clone(&self.applied_source_volume); - return cosmic::Task::future(async move { - tokio::time::sleep(Duration::from_millis(128)).await; - _ = client - .conn - .set_source_volume(volume.load(atomic::Ordering::Relaxed)) - .await; - Message::ReattachClient(Arc::new(client)).into() - }); - } + return self + .model + .set_source_volume(volume) + .map(|message| Message::Subscription(message).into()); } Message::ToggleMediaControlsInTopPanel(enabled) => { self.config.show_media_controls_in_top_panel = enabled; if let Ok(helper) = cosmic::cosmic_config::Config::new(Self::APP_ID, AudioAppletConfig::VERSION) - && let Err(err) = self.config.write_entry(&helper) { - tracing::error!(?err, "Error writing config"); + if let Err(err) = self.config.write_entry(&helper) { + tracing::error!(?err, "Error writing config"); + } } } Message::CloseRequested(id) => { @@ -546,13 +457,9 @@ impl cosmic::Application for Audio { } }, Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); - } - Message::Client(client) => { - if let Some(client) = Arc::into_inner(client) { - self.audio_client = Some(client); - self.model = model::Model::default(); - } + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } @@ -569,50 +476,7 @@ impl cosmic::Application for Audio { }), mpris_subscription::mpris_subscription(0).map(Message::Mpris), activation_token_subscription(0).map(Message::Token), - Subscription::run(|| { - iced::stream::channel( - 1, - move |mut emitter: futures::channel::mpsc::Sender<_>| async move { - loop { - let mut client = match audio_client::connect().await { - Ok(client) => client, - Err(why) => { - if let zlink::Error::Io(ref why) = why - && why.kind() == std::io::ErrorKind::NotFound - { - tracing::error!( - "cosmic-settings-daemon varlink service not found." - ); - } else { - tracing::error!( - ?why, - "failed to connect to cosmic-settings's varlink service" - ); - } - - tokio::time::sleep(std::time::Duration::from_secs(3)).await; - continue; - } - }; - - if let Ok(Ok(mut stream)) = client.recv_events().await { - _ = emitter.send(Message::Client(Arc::new(client))).await; - while let Some(message) = stream.next().await { - match message { - Ok(event) => { - _ = emitter.send(Message::Subscription(event)).await; - } - Err(why) => { - tracing::error!(?why, "event error"); - } - } - } - } - } - }, - ) - }), - rectangle_tracker_subscription(0).map(|update| Message::Rectangle(update.1)), + Subscription::run(|| css::watch().map(Message::Subscription)), ]) } @@ -623,94 +487,63 @@ impl cosmic::Application for Audio { .icon_button(self.output_icon_name()) .on_press_down(Message::TogglePopup); - const WHEEL_STEP: f32 = 5.0; // 5% par cran logique - // Wayland axis_v120 envoie un cran physique en rafale de plusieurs - // ScrollDelta::Pixels (5–8 events ~15–20px), pour ~120px par cran. On - // accumule ces sub-events dans un thread_local et on n'émet qu'au - // passage d'un seuil — sinon `signum()` faisait croire que chaque - // sub-event = un cran, et un seul cran physique faisait chuter le - // volume jusqu'à 0 ("coupe le son"). - const PIXEL_THRESHOLD: f32 = 15.0; // px par cran logique - std::thread_local! { - static PIXEL_ACC: std::cell::Cell = const { std::cell::Cell::new(0.0) }; - } + const WHEEL_STEP: f32 = 5.0; // 5% per wheel event let btn = crate::mouse_area::MouseArea::new(btn).on_mouse_wheel(|delta| { let scroll_vector = match delta { - iced::mouse::ScrollDelta::Lines { y, .. } => { - PIXEL_ACC.with(|a| a.set(0.0)); - y * WHEEL_STEP - } - iced::mouse::ScrollDelta::Pixels { y, .. } => { - PIXEL_ACC.with(|acc_cell| { - let acc = acc_cell.get() + y; - let steps = (acc / PIXEL_THRESHOLD).trunc(); - acc_cell.set(acc - steps * PIXEL_THRESHOLD); - steps * WHEEL_STEP - }) - } + iced::mouse::ScrollDelta::Lines { y, .. } => y.signum() * WHEEL_STEP, // -1/0/1 + iced::mouse::ScrollDelta::Pixels { y, .. } => y.signum(), // -1/0/1 }; if scroll_vector == 0.0 { return Message::Ignore; } - let new_volume = (self.model.active_sink.volume as f64 + (scroll_vector as f64)) + let new_volume = (self.model.sink_volume as f64 + (scroll_vector as f64)) .clamp(0.0, self.max_sink_volume as f64); - Message::SetSinkVolume(new_volume.round() as u32) + Message::SetSinkVolume(new_volume as u32) }); - let mut has_playback_buttons = false; let playback_buttons = (!self.core.applet.suggested_bounds.as_ref().is_some_and(|c| { // if we have a configure for width and height, we're in a overflow popup c.width > 0. && c.height > 0. })) .then(|| self.playback_buttons()); - let mut ret = if let Some(playback_buttons) = playback_buttons - && !playback_buttons.is_empty() - { - has_playback_buttons = true; - Element::from(match self.core.applet.anchor { - PanelAnchor::Left | PanelAnchor::Right => Element::from( - applet_column::Column::with_children(playback_buttons) - .push(btn) - .align_x(Alignment::Center) - .height(Length::Shrink) - // TODO configurable variable from the panel? - .spacing( - -(self.core.applet.suggested_padding(true).0 as f32) - * self.core.applet.padding_overlap, + self.core + .applet + .autosize_window( + if let Some(playback_buttons) = playback_buttons + && !playback_buttons.is_empty() + { + match self.core.applet.anchor { + PanelAnchor::Left | PanelAnchor::Right => Element::from( + applet_column::Column::with_children(playback_buttons) + .push(btn) + .align_x(Alignment::Center) + .height(Length::Shrink) + // TODO configurable variable from the panel? + .spacing( + -(self.core.applet.suggested_padding(true).0 as f32) + * self.core.applet.padding_overlap, + ), ), - ), - PanelAnchor::Top | PanelAnchor::Bottom => { - applet_row::Row::with_children(playback_buttons) - .push(btn) - .align_y(Alignment::Center) - .width(Length::Shrink) - // TODO configurable variable from the panel? - .spacing( - -(self.core.applet.suggested_padding(true).0 as f32) - * self.core.applet.padding_overlap, - ) - .into() - } - }) - } else { - btn.into() - }; - - if let Some(tracker) = self.rectangle_tracker.as_ref() - && has_playback_buttons - { - ret = tracker.container(0, ret).into() - } - - if !self.core.applet.suggested_bounds.as_ref().is_some_and(|c| { - // if we have a configure for width and height, we're in a overflow popup - c.width > 0. && c.height > 0. - }) { - ret = self.core.applet.autosize_window(ret).into(); - } - ret + PanelAnchor::Top | PanelAnchor::Bottom => { + applet_row::Row::with_children(playback_buttons) + .push(btn) + .align_y(Alignment::Center) + .width(Length::Shrink) + // TODO configurable variable from the panel? + .spacing( + -(self.core.applet.suggested_padding(true).0 as f32) + * self.core.applet.padding_overlap, + ) + .into() + } + } + } else { + btn.into() + }, + ) + .into() } fn view_window(&self, _id: window::Id) -> Element<'_, Message> { @@ -718,21 +551,19 @@ impl cosmic::Application for Audio { space_xxs, space_s, .. } = theme::active().cosmic().spacing; - let sink: Option<&str> = self + let sink = self .model - .sinks - .active() - .map(|pos| self.model.sinks.sorted_display[pos].as_ref()); - let source: Option<&str> = self + .active_sink() + .and_then(|pos| self.model.sinks().get(pos)); + let source = self .model - .sources - .active() - .map(|pos| self.model.sources.sorted_display[pos].as_ref()); + .active_source() + .and_then(|pos| self.model.sources().get(pos)); let mut audio_content = { let output_slider = slider( 0..=self.max_sink_volume, - self.model.active_sink.volume, + self.model.sink_volume, Message::SetSinkVolume, ) .width(Length::FillPortion(5)) @@ -740,7 +571,7 @@ impl cosmic::Application for Audio { let input_slider = slider( 0..=self.max_source_volume, - self.model.active_source.volume, + self.model.source_volume, Message::SetSourceVolume, ) .width(Length::FillPortion(5)) @@ -759,7 +590,7 @@ impl cosmic::Application for Audio { .line_height(24) .on_press(Message::ToggleSinkMute), output_slider, - container(text(&self.model.active_sink.volume_text).size(16)) + container(text(&self.model.sink_volume_text).size(16)) .width(Length::FillPortion(1)) .align_x(Alignment::End) ] @@ -778,7 +609,7 @@ impl cosmic::Application for Audio { .line_height(24) .on_press(Message::ToggleSourceMute), input_slider, - container(text(&self.model.active_source.volume_text).size(16)) + container(text(&self.model.source_volume_text).size(16)) .width(Length::FillPortion(1)) .align_x(Alignment::End) ] @@ -793,7 +624,7 @@ impl cosmic::Application for Audio { Some(sink) => sink.to_owned(), None => fl!("no-device"), }, - &self.model.sinks.sorted_display, + self.model.sinks(), Message::OutputToggle, Message::SetDefaultSink, ), @@ -804,7 +635,7 @@ impl cosmic::Application for Audio { Some(source) => source.to_owned(), None => fl!("no-device"), }, - &self.model.sources.sorted_display, + self.model.sources(), Message::InputToggle, Message::SetDefaultSource, ) @@ -860,15 +691,19 @@ impl cosmic::Application for Audio { } if let Some(play) = self.is_play() { control_elements.push( - button::icon(icon::from_name(if play { PLAY } else { PAUSE }).symbolic(true)) - .extra_small() - .class(cosmic::theme::Button::AppletIcon) - .on_press(if play { - Message::MprisRequest(MprisRequest::Play) - } else { - Message::MprisRequest(MprisRequest::Pause) - }) - .into(), + button::icon( + icon::from_name(if play { PLAY } else { PAUSE }) + .size(32) + .symbolic(true), + ) + .extra_small() + .class(cosmic::theme::Button::AppletIcon) + .on_press(if play { + Message::MprisRequest(MprisRequest::Play) + } else { + Message::MprisRequest(MprisRequest::Pause) + }) + .into(), ); } if let Some(go_next) = self.go_next(32) { @@ -919,21 +754,20 @@ impl cosmic::Application for Audio { } } -fn revealer<'a>( +fn revealer( open: bool, title: String, selected: String, - devices: &'a [Arc], + devices: &[String], toggle: Message, mut change: impl FnMut(usize) -> Message + 'static, -) -> widget::Column<'a, Message, crate::Theme, Renderer> { +) -> widget::Column<'static, Message, crate::Theme, Renderer> { if open { - devices.iter().enumerate().fold( + devices.iter().cloned().enumerate().fold( column![revealer_head(open, title, selected, toggle)].width(Length::Fill), - move |col, (id, name)| { + |col, (id, name)| { col.push( - text::body(name.as_ref()) - .apply(menu_button) + menu_button(text::body(name)) .on_press(change(id)) .width(Length::Fill) .padding([8, 48]), @@ -951,9 +785,9 @@ fn revealer_head( selected: String, toggle: Message, ) -> cosmic::widget::Button<'static, Message> { - cosmic::widget::column::with_capacity(2) - .push(text::body(title).width(Length::Fill)) - .push(text::caption(selected)) - .apply(menu_button) - .on_press(toggle) + menu_button(column![ + text::body(title).width(Length::Fill), + text::caption(selected), + ]) + .on_press(toggle) } diff --git a/cosmic-applet-audio/src/model.rs b/cosmic-applet-audio/src/model.rs deleted file mode 100644 index 5aff7ba4..00000000 --- a/cosmic-applet-audio/src/model.rs +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2026 System76 -// SPDX-License-Identifier: GPL-3.0-only - -use std::sync::Arc; - -use cosmic_settings_audio_client::{self as audio_client, Availability, RouteInfo}; -use intmap::IntMap; - -pub type DeviceId = u32; -pub type NodeId = u32; - -#[derive(Debug, Default)] -pub struct Model { - pub device_routes: IntMap>, - pub node_devices: IntMap>, - pub sinks: Nodes, - pub sources: Nodes, - pub active_sink: ActiveNode, - pub active_source: ActiveNode, - pub default_sink: Option, - pub default_source: Option, -} - -#[derive(Debug, Default)] -pub struct Nodes { - active: Option, - pub sorted_display: Box<[Arc]>, - pub sorted_index: Box<[u16]>, - pub balance: Vec>, - pub card_profile_device: Vec>, - pub description: Vec, - pub devices: Vec>, - pub display: Vec>, - pub mute: Vec, - pub name: Vec, - pub id: Vec, - pub volume: Vec, -} - -impl Nodes { - pub fn active(&self) -> Option { - self.active.and_then(|active| { - self.sorted_index - .iter() - .position(|idx| *idx as usize == active) - }) - } - - pub fn dropdown_sort(&mut self) { - let mut enumerated_displays = self - .display - .clone() - .into_iter() - .enumerate() - .map(|(index, display)| (index as u16, display)) - .collect::>(); - enumerated_displays.sort_by_key(|v| v.1.clone()); - let (indexes, displays): (Vec<_>, Vec<_>) = enumerated_displays.into_iter().unzip(); - self.sorted_display = displays.into_boxed_slice(); - self.sorted_index = indexes.into_boxed_slice(); - } - - pub fn remove(&mut self, node_id: u32) -> bool { - let Some(pos) = self.id.iter().position(|id| node_id == *id) else { - return false; - }; - self.balance.remove(pos); - self.card_profile_device.remove(pos); - self.description.remove(pos); - self.devices.remove(pos); - self.display.remove(pos); - self.mute.remove(pos); - self.name.remove(pos); - self.id.remove(pos); - self.volume.remove(pos); - self.dropdown_sort(); - match self.active { - Some(active) if active == pos => self.active = None, - Some(active) if active > pos => self.active = Some(active - 1), - _ => {} - } - true - } -} - -#[derive(Debug, Default)] -pub struct ActiveNode { - pub volume_text: String, - pub volume: u32, - pub mute: bool, -} - -impl Model { - pub fn update(&mut self, event: audio_client::Event) { - tracing::debug!(?event, "update"); - match event { - audio_client::Event::NodeMute(node_id, mute) => { - if let Some(pos) = self.sinks.id.iter().position(|id| node_id == *id) { - self.sinks.mute[pos] = mute; - if self.sinks.active == Some(pos) { - self.active_sink.mute = mute; - } - } else if let Some(pos) = self.sources.id.iter().position(|id| node_id == *id) { - self.sources.mute[pos] = mute; - if self.sources.active == Some(pos) { - self.active_source.mute = mute; - } - } - } - - audio_client::Event::NodeVolume(node_id, volume, balance) => { - if let Some(pos) = self.sinks.id.iter().position(|id| node_id == *id) { - self.sinks.volume[pos] = volume; - self.sinks.balance[pos] = balance; - if self.default_sink.as_ref().is_some_and(|&id| id == node_id) - && let Some(pos) = self.sinks.active - { - self.active_sink.mute = self.sinks.mute[pos]; - self.active_sink.volume = self.sinks.volume[pos]; - self.active_sink.volume_text = self.active_sink.volume.to_string(); - } - } else if let Some(pos) = self.sources.id.iter().position(|id| node_id == *id) { - self.sources.volume[pos] = volume; - self.sources.balance[pos] = balance; - if self - .default_source - .as_ref() - .is_some_and(|&id| id == node_id) - && let Some(pos) = self.sources.active - { - self.active_source.mute = self.sources.mute[pos]; - self.active_source.volume = self.sources.volume[pos]; - self.active_source.volume_text = self.active_source.volume.to_string(); - } - } - } - - audio_client::Event::DefaultSink(node_id) => { - self.default_sink = Some(node_id); - if let Some(pos) = self.sinks.id.iter().position(|&id| id == node_id) { - self.sinks.active = Some(pos); - self.active_sink.mute = self.sinks.mute[pos]; - self.active_sink.volume = self.sinks.volume[pos]; - self.active_sink.volume_text = self.active_sink.volume.to_string(); - } - } - - audio_client::Event::DefaultSource(node_id) => { - self.default_source = Some(node_id); - if let Some(pos) = self.sources.id.iter().position(|&id| id == node_id) { - self.sources.active = Some(pos); - self.active_source.mute = self.sources.mute[pos]; - self.active_source.volume = self.sources.volume[pos]; - self.active_source.volume_text = self.active_source.volume.to_string(); - } - } - - audio_client::Event::Node(node_id, node) => { - self.node_devices.insert(node_id, node.device_id); - if node.is_sink { - let pos = if let Some(pos) = self.sinks.id.iter().position(|&id| id == node_id) - { - self.sinks.description[pos] = self.translate(&node.description); - self.sinks.name[pos] = node.name; - self.sinks.card_profile_device[pos] = node.card_profile_device; - pos - } else { - self.sinks.display.push(Arc::default()); - self.sinks - .description - .push(self.translate(&node.description)); - self.sinks.id.push(node_id); - self.sinks.volume.push(0); - self.sinks.balance.push(None); - self.sinks.mute.push(false); - self.sinks.name.push(node.name); - self.sinks.devices.push(node.device_id); - self.sinks - .card_profile_device - .push(node.card_profile_device); - self.sinks.id.len() - 1 - }; - - self.sinks.display[pos] = node - .device_id - .zip(node.card_profile_device) - .and_then(|(device_id, node_card_profile_device)| { - let routes = self.device_routes.get(device_id)?; - for route in routes { - if matches!(route.availability, Availability::No) || !route.is_sink - { - continue; - } - - if route.devices.contains(&node_card_profile_device) { - return Some(node_name( - &self.translate(&route.description), - &self.sinks.description[pos], - )); - } - } - - None - }) - .unwrap_or_else(|| { - node_name( - &node.device_profile_description, - &self.sinks.description[pos], - ) - }); - - self.sinks.dropdown_sort(); - - if let Some(default_node_id) = self.default_sink - && default_node_id == node_id - { - self.sinks.active = Some(pos); - self.active_sink.mute = self.sinks.mute[pos]; - self.active_sink.volume = self.sinks.volume[pos]; - self.active_sink.volume_text = self.active_sink.volume.to_string(); - } - } else { - let pos = - if let Some(pos) = self.sources.id.iter().position(|&id| id == node_id) { - self.sources.description[pos] = self.translate(&node.description); - self.sources.name[pos] = node.name; - self.sources.card_profile_device[pos] = node.card_profile_device; - pos - } else { - self.sources - .description - .push(self.translate(&node.description)); - self.sources.display.push(Arc::default()); - self.sources.id.push(node_id); - self.sources.volume.push(0); - self.sources.balance.push(None); - self.sources.mute.push(false); - self.sources.name.push(node.name); - self.sources.devices.push(node.device_id); - self.sources - .card_profile_device - .push(node.card_profile_device); - self.sources.id.len() - 1 - }; - - if let Some(name) = node - .device_id - .zip(node.card_profile_device) - .map(|(device_id, node_card_profile_device)| { - let routes = self.device_routes.get(device_id)?; - for route in routes { - if route.is_sink || matches!(route.availability, Availability::No) { - continue; - } - - if route.devices.contains(&node_card_profile_device) { - return Some(node_name( - &self.translate(&route.description), - &self.sources.description[pos], - )); - } - } - - None - }) - .unwrap_or_else(|| { - Some(node_name( - &node.device_profile_description, - &self.sources.description[pos], - )) - }) - { - self.sources.display[pos] = name; - self.sources.dropdown_sort(); - } else { - // Remove sources that are unplugged. - self.sources.remove(node_id); - return; - } - - if let Some(default_node_id) = self.default_source - && default_node_id == node_id - { - self.sources.active = Some(pos); - self.active_source.mute = self.sources.mute[pos]; - self.active_source.volume = self.sources.volume[pos]; - self.active_source.volume_text = self.active_source.volume.to_string(); - } - } - } - - audio_client::Event::ActiveRoute(device_id, _index, route) => { - self.update_device_names(device_id, &route); - } - - audio_client::Event::Route(device_id, index, route) => { - let routes = self.device_routes.entry(device_id).or_default(); - if index == 0 { - *routes = vec![route]; - } else { - if routes.len() < index as usize + 1 { - let additional = (index as usize + 1) - routes.capacity(); - routes.reserve_exact(additional); - routes.extend(std::iter::repeat_n(RouteInfo::default(), additional)); - } - routes[index as usize] = route; - } - } - - audio_client::Event::RemoveNode(node_id) => { - self.node_devices.remove(node_id); - - if !self.sinks.remove(node_id) { - self.sources.remove(node_id); - } - } - - audio_client::Event::RemoveDevice(device_id) => { - self.device_routes.remove(device_id); - } - - _ => (), - } - } - - fn update_device_names(&mut self, device_id: DeviceId, route: &RouteInfo) { - if matches!(route.availability, Availability::No) { - return; - } - - let compatible_nodes = self.node_devices.iter().filter_map(|(node, &dev_id)| { - if dev_id? == device_id { - Some(node) - } else { - None - } - }); - - if route.is_sink { - for n_id in compatible_nodes { - let Some(pos) = self.sinks.id.iter().position(|&node| node == n_id) else { - continue; - }; - - let Some(card_profile_device) = self.sinks.card_profile_device[pos] else { - continue; - }; - - if route.devices.contains(&card_profile_device) { - self.sinks.display[pos] = node_name( - &self.translate(&route.description), - &self.sinks.description[pos], - ); - self.sinks.dropdown_sort(); - break; - } - } - } else { - for n_id in compatible_nodes { - let Some(pos) = self.sources.id.iter().position(|&node| node == n_id) else { - continue; - }; - - let Some(card_profile_device) = self.sources.card_profile_device[pos] else { - continue; - }; - - if route.devices.contains(&card_profile_device) { - self.sources.display[pos] = node_name( - &self.translate(&route.description), - &self.sources.description[pos], - ); - self.sources.dropdown_sort(); - break; - } - } - } - } - - pub fn translate(&self, description: &str) -> String { - description - .replace("High Definition", "HD") - .replace("DisplayPort", "DP") - .replace("Controller", "") - } -} - -fn node_name(route: &str, node: &str) -> Arc { - if route.is_empty() { - node.to_owned() - } else { - [route, " - ", node].concat() - } - .into() -} diff --git a/cosmic-applet-audio/src/mouse_area.rs b/cosmic-applet-audio/src/mouse_area.rs index 94efb4f7..6ae8547a 100644 --- a/cosmic-applet-audio/src/mouse_area.rs +++ b/cosmic-applet-audio/src/mouse_area.rs @@ -5,7 +5,7 @@ use cosmic::iced::core::Point; use cosmic::iced::core::{ Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Widget, - event::Event, + event::{self, Event}, layout, mouse, overlay, renderer, touch, widget::{Operation, Tree, tree}, }; @@ -307,19 +307,6 @@ fn update( shell: &mut Shell<'_, Message>, state: &mut State, ) { - // Handle wheel events before the bounds check. The panel's nested - // compositor routes axis events to this surface only when the pointer - // is over the applet, but the cursor coordinates it sends may be in - // panel-local space rather than surface-local space. This makes - // cursor.is_over() unreliable for scroll events. - if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event { - if let Some(message) = widget.on_mouse_wheel.as_ref() { - shell.publish((message)(*delta)); - shell.capture_event(); - return; - } - } - if !cursor.is_over(layout.bounds()) { if !state.is_out_of_bounds { if widget @@ -429,4 +416,12 @@ fn update( } } } + + if let Some(message) = widget.on_mouse_wheel.as_ref() { + if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event { + shell.publish((message)(*delta)); + shell.capture_event(); + return; + } + } } diff --git a/cosmic-applet-battery/Cargo.toml b/cosmic-applet-battery/Cargo.toml index 3b7a37e4..2218f638 100644 --- a/cosmic-applet-battery/Cargo.toml +++ b/cosmic-applet-battery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-battery" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -12,7 +12,7 @@ drm = "0.14.1" futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true +libcosmic.workspace = true rust-embed.workspace = true rustc-hash.workspace = true tokio.workspace = true @@ -24,7 +24,9 @@ zbus.workspace = true serde.workspace = true [dependencies.cosmic-settings-upower-subscription] -path = "../../cosmic-settings/subscriptions/upower" +git = "https://github.com/pop-os/cosmic-settings" +# path = "../../cosmic-settings/subscriptions/upower" [dependencies.cosmic-settings-daemon-subscription] -path = "../../cosmic-settings/subscriptions/settings-daemon" +git = "https://github.com/pop-os/cosmic-settings" +# path = "../../cosmic-settings/subscriptions/settings-daemon" diff --git a/cosmic-applet-battery/i18n/da/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/da/cosmic_applet_battery.ftl index 28cf327a..e69de29b 100644 --- a/cosmic-applet-battery/i18n/da/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/da/cosmic_applet_battery.ftl @@ -1,14 +0,0 @@ -power-settings = Strøm- og Batteriindstillinger... -hours = t -until-empty = indtil tom -battery-desc = Reduceret strømforbrug og ydeevne. -max-charge = Forøg dit batteris levetid, ved at angive en maksimal opladningsværdi på 80% -balanced = Balanceret -battery = Batteri -seconds = s -dgpu-running = Diskret GPU er aktiv og kan reducere batterilevetiden -performance = Høj Ydeevne -performance-desc = Høj ydeevne og strømforbrug. -minutes = m -balanced-desc = Standard ydeevne og batteriforbrug. -dgpu-applications = Applikationer som bruger { $gpu_name } diskret GPU diff --git a/cosmic-applet-battery/i18n/de/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/de/cosmic_applet_battery.ftl index 283930e2..ec518e5f 100644 --- a/cosmic-applet-battery/i18n/de/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/de/cosmic_applet_battery.ftl @@ -9,6 +9,6 @@ seconds = s minutes = m hours = h until-empty = bis leer -power-settings = Energie- und Akkueinstellungen ... +power-settings = Energie- und Akkueinstellungen... dgpu-running = Dedizierte GPU ist aktiv und kann die Akkulaufzeit reduzieren dgpu-applications = Anwendungen, welche die dedizierte GPU { $gpu_name } nutzen diff --git a/cosmic-applet-battery/i18n/el/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/el/cosmic_applet_battery.ftl index 06eca770..e69de29b 100644 --- a/cosmic-applet-battery/i18n/el/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/el/cosmic_applet_battery.ftl @@ -1,14 +0,0 @@ -battery = Μπαταρία -power-settings = Ρυθμίσεις ενέργειας και μπαταρίας... -hours = ώ -until-empty = μέχρι την αποφόρτιση -battery-desc = Μειωμένη χρήση ενέργειας και επιδόσεις. -max-charge = Επεκτείνετε τη διάρκεια ζωής της μπαταρίας σας ορίζοντας ως μέγιστη τιμή φόρτισης το 80% -balanced = Ισορροπημένη -seconds = δ -dgpu-running = Η ανεξάρτητη GPU είναι ενεργή και μπορεί να μειώσει τη διάρκεια ζωής της μπαταρίας -performance = Υψηλές επιδόσεις -performance-desc = Υψηλές επιδόσεις και χρήση ενέργειας. -minutes = λ -balanced-desc = Τυπικές επιδόσεις και χρήση μπαταρίας. -dgpu-applications = Εφαρμογές που χρησιμοποιούν την ανεξάρτητη GPU { $gpu_name } diff --git a/cosmic-applet-battery/i18n/en-GB/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/en-GB/cosmic_applet_battery.ftl index 11833e03..e69de29b 100644 --- a/cosmic-applet-battery/i18n/en-GB/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/en-GB/cosmic_applet_battery.ftl @@ -1,14 +0,0 @@ -power-settings = Power & Battery settings... -hours = h -until-empty = until empty -battery-desc = Reduced power usage and performance. -max-charge = Increase the lifespan of your battery by setting a maximum charge value of 80% -balanced = Balanced -battery = Battery -seconds = s -dgpu-running = Discrete GPU is active and can reduce battery life -performance = High Performance -performance-desc = High performance and power usage. -minutes = m -balanced-desc = Standard performance and battery usage. -dgpu-applications = Applications using { $gpu_name } discrete GPU diff --git a/cosmic-applet-battery/i18n/fil/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/fil/cosmic_applet_battery.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-battery/i18n/gl/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/gl/cosmic_applet_battery.ftl deleted file mode 100644 index 0146556a..00000000 --- a/cosmic-applet-battery/i18n/gl/cosmic_applet_battery.ftl +++ /dev/null @@ -1,14 +0,0 @@ -battery = Batería -battery-desc = Reduce o consumo de enerxía e o rendemento. -balanced = Balanceado -balanced-desc = Rendemento e consumo de batería estándar. -performance = Alto rendemento -performance-desc = Alto rendemento e maior consumo de enerxía. -max-charge = Aumenta a vida útil da batería limitando a carga máxima ao 80 % -seconds = s -minutes = m -hours = h -until-empty = ata baleirar -power-settings = Axustes de enexía e batería... -dgpu-running = A GPU dedicada está activa e pode reducir a duración da batería -dgpu-applications = Aplicacións que están a usar a GPU dedicada { $gpu_name } diff --git a/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl index 01626a96..814d3605 100644 --- a/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl @@ -1,13 +1,13 @@ battery = Akkumulátor -battery-desc = Csökkentett energiafogyasztás és teljesítmény. +battery-desc = Csökkentett energiafogyasztás és teljesítmény balanced = Kiegyensúlyozott -balanced-desc = Normál teljesítmény és akkumulátorhasználat. +balanced-desc = Normál teljesítmény és akkumulátorhasználat performance = Nagy teljesítmény -performance-desc = Nagy teljesítmény és energiafogyasztás. -max-charge = Az akkumulátor élettartamának növelése érdekében állítsd a maximális töltési szintet 80%-ra -seconds = mp -minutes = p -hours = ó +performance-desc = Nagy teljesítmény és energiafogyasztás +max-charge = Az akkumulátor élettartamának növelése érdekében állítsa a maximális töltési szintet 80%-ra +seconds = másodperc +minutes = perc +hours = óra until-empty = a lemerülésig power-settings = Energia- és akkumulátorbeállítások… dgpu-running = A dedikált GPU aktív, ami csökkentheti az akkumulátor élettartamát diff --git a/cosmic-applet-battery/i18n/it/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/it/cosmic_applet_battery.ftl index 375e29e0..6f3bbd9c 100644 --- a/cosmic-applet-battery/i18n/it/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/it/cosmic_applet_battery.ftl @@ -1,14 +1,14 @@ -battery = Batteria -battery-desc = Prestazioni e consumo energetico ridotti. -balanced = Equilibrato -balanced-desc = Prestazioni e consumo energetico normali. -performance = Prestazioni elevate -performance-desc = Prestazioni elevate e consumo energetico. -max-charge = Aumenta la durata della batteria impostando un valore massimo di carica dell’80% +battery = Risparmio energetico +battery-desc = Consumi minimi, performance ridotta. +balanced = Bilanciato +balanced-desc = Consumi bilanciati, performance dinamica. +performance = Performance +performance-desc = Consumi alti, performance massima. +max-charge = Migliora la durata di vita della batteria caricandola fino all'80% seconds = s minutes = m hours = h -until-empty = finché non è vuoto +until-empty = fino alla scarica power-settings = Impostazioni energetiche... dgpu-running = La GPU discreta è attiva e può ridurre la durata della batteria dgpu-applications = Applicazioni che stanno usando la GPU discreta { $gpu_name } diff --git a/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl index 4f531fec..e69de29b 100644 --- a/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl @@ -1,14 +0,0 @@ -battery = Betarî -seconds = ç -minutes = x -hours = d -until-empty = heya vala dibe -power-settings = Sazkariyên hêz û betariyê... -battery-desc = Bikaranîna hêzê kêmkirî û performans. -balanced = Hevseng -balanced-desc = Performansa standard û bikaranîna betariyê. -performance = Performansa bilind -performance-desc = Performansa bilind û bikaranîna hêzê. -max-charge = Jiyana betariyê xwe dirêj bike bi riya danîna sînorê herî mezin yê tijîkrinê %80 -dgpu-running = YKG a veqetandî çalak e û dikare jiyana betariyê kêm bike -dgpu-applications = Sepanên ku YKG a veqetandî ya { $gpu_name } bi kar tînin diff --git a/cosmic-applet-battery/i18n/lo/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/lo/cosmic_applet_battery.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-battery/i18n/nl/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/nl/cosmic_applet_battery.ftl index b8ba9879..bfa3f37e 100644 --- a/cosmic-applet-battery/i18n/nl/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/nl/cosmic_applet_battery.ftl @@ -1,9 +1,9 @@ battery = Batterij -battery-desc = Verminderde prestaties en lager energieverbruik. +battery-desc = Energiebesparing en lagere prestaties. balanced = Gebalanceerd -balanced-desc = Normale prestaties en matig energieverbruik. +balanced-desc = Normale prestaties en batterijverbruik. performance = Hoge prestaties -performance-desc = Maximale prestaties en hoger energieverbruik. +performance-desc = Hoge prestaties en energieverbruik. max-charge = Verleng de levensduur van uw batterij door een maximale laadwaarde van 80% in te stellen seconds = s minutes = m diff --git a/cosmic-applet-battery/i18n/pt-BR/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/pt-BR/cosmic_applet_battery.ftl index 3bd3b657..e5a72d03 100644 --- a/cosmic-applet-battery/i18n/pt-BR/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/pt-BR/cosmic_applet_battery.ftl @@ -2,13 +2,13 @@ battery = Bateria battery-desc = Uso reduzido de energia e desempenho limitado. balanced = Balanceado balanced-desc = Desempenho padrão e uso de bateria moderado. -performance = Alto desempenho +performance = Alto Desempenho performance-desc = Máximo desempenho e alto uso de energia. max-charge = Aumente a vida útil da sua bateria definindo um valor máximo de carga de 80% seconds = s minutes = m hours = h -until-empty = até ficar descarregada +until-empty = até esvaziar power-settings = Configurações de energia e bateria... -dgpu-running = A GPU dedicada está ativa e pode reduzir a vida útil da bateria -dgpu-applications = Aplicativos usando a GPU dedicada { $gpu_name } +dgpu-running = GPU discreta está ativa e pode reduzir a vida útil da bateria +dgpu-applications = Aplicativos usando GPU discreta { $gpu_name } diff --git a/cosmic-applet-battery/i18n/sat/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/sat/cosmic_applet_battery.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-battery/i18n/sr/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/sr/cosmic_applet_battery.ftl index 3d242270..e69de29b 100644 --- a/cosmic-applet-battery/i18n/sr/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/sr/cosmic_applet_battery.ftl @@ -1,14 +0,0 @@ -power-settings = Подешавања напајања и батерије... -hours = ч -until-empty = до празне -battery-desc = Смањен учинак и употреба струје. -balanced = Уравнотежено -battery = Батерија -seconds = с -performance = Најбрже -performance-desc = Висок учинак и употреба струје. -minutes = м -balanced-desc = Уобичајени учинак и употреба батерије. -max-charge = Повећајте век трајања батерије подешавањем највише вредности пуњења на 80% -dgpu-running = Засебна графичка је покренута и може умањити век трајања батерије -dgpu-applications = Програми који користе засебну графичку { $gpu_name } diff --git a/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl index 608f8a60..33c18ba3 100644 --- a/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl @@ -6,9 +6,9 @@ performance = 高效能 performance-desc = 高效能與高耗電量。 max-charge = 將電池充電上限設定為 80%,以延長電池使用壽命 seconds = 秒 -minutes = 分鍾 -hours = 小時 +minutes = 分 +hours = 時 until-empty = 直到電量耗盡 power-settings = 電源與電池設定… dgpu-running = 獨立顯示卡已啟用,可能會縮短電池續航力 -dgpu-applications = 使用獨立顯示卡 { $gpu_name } 的應用程式 +dgpu-applications = 使用 { $gpu_name } 獨立顯示卡的應用程式 diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index 95ad828d..67e513c3 100644 --- a/cosmic-applet-battery/src/app.rs +++ b/cosmic-applet-battery/src/app.rs @@ -40,7 +40,7 @@ use cosmic_settings_upower_subscription::{ }; use rustc_hash::FxHashMap; -use std::{path::PathBuf, time::Duration}; +use std::{path::PathBuf, sync::LazyLock, time::Duration}; use tokio::sync::mpsc::UnboundedSender; // XXX improve @@ -169,24 +169,9 @@ impl CosmicBatteryApplet { self.charging_limit = Some(limit); self.update_battery(self.battery_percent, self.on_battery); } - - fn panel_icon_name(&self) -> &str { - if self.no_battery { - if self.screen_brightness.is_some() { - self.display_icon_name.as_str() - } else if self.kbd_brightness.is_some() { - "keyboard-brightness-symbolic" - } else { - "plugged-into-power-symbolic" - } - } else { - self.icon_name.as_str() - } - } } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), @@ -213,7 +198,7 @@ enum Message { OpenSettings, SettingsDaemon(settings_daemon::Event), ZbusConnection(zbus::Result), - Surface(surface::Action), + Surface(surface::Action), } impl cosmic::Application for CosmicBatteryApplet { @@ -366,35 +351,23 @@ impl cosmic::Application for CosmicBatteryApplet { let _ = tx.send(KeyboardBacklightRequest::Get); } + let new_id = window::Id::unique(); + self.popup.replace(new_id); + + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + Some((1, 1)), + None, + None, + ); if let Some(tx) = self.power_profile_sender.as_ref() { let _ = tx.send(PowerProfileRequest::Get); } if let Some(tx) = self.update_trigger.as_ref() { let _ = tx.send(()); } - let mut tasks = vec![cosmic::surface::surface_task( - cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); - - let popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - Some((1, 1)), - None, - None, - ); - popup_settings - }, - None, - ), - )]; - if let Some(tx) = &self.settings_daemon_sender { - let _ = tx.send(settings_daemon::Request::GetDisplayBrightness); - let _ = tx.send(settings_daemon::Request::GetMaxDisplayBrightness); - } + let mut tasks = vec![get_popup(popup_settings)]; // Try again every time a popup is opened if self.charging_limit.is_none() { tasks.push(Task::perform(get_charging_limit(), |limit| { @@ -526,13 +499,15 @@ impl cosmic::Application for CosmicBatteryApplet { } }, Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } Task::none() } - fn view(&self) -> Element<'_, Message> { + fn view(&self) -> Element { let is_horizontal = match self.core.applet.anchor { PanelAnchor::Top | PanelAnchor::Bottom => true, PanelAnchor::Left | PanelAnchor::Right => false, @@ -542,9 +517,19 @@ impl cosmic::Application for CosmicBatteryApplet { let applet_padding = self.core.applet.suggested_padding(true); let mut children = vec![ - icon::from_name(self.panel_icon_name()) - .size(suggested_size.0) - .into(), + icon::from_name(if self.no_battery { + if self.screen_brightness.is_some() { + self.display_icon_name.as_str() + } else if self.kbd_brightness.is_some() { + "keyboard-brightness-symbolic" + } else { + self.icon_name.as_str() + } + } else { + self.icon_name.as_str() + }) + .size(suggested_size.0) + .into(), ]; if self.config.show_percentage && !self.no_battery { diff --git a/cosmic-applet-bluetooth/Cargo.toml b/cosmic-applet-bluetooth/Cargo.toml index 8f92bb04..03b67388 100644 --- a/cosmic-applet-bluetooth/Cargo.toml +++ b/cosmic-applet-bluetooth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-bluetooth" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -10,7 +10,7 @@ bluer = { version = "0.17", features = ["bluetoothd", "id"] } futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true +libcosmic.workspace = true fastrand = "2.3.0" rust-embed.workspace = true rustc-hash.workspace = true diff --git a/cosmic-applet-bluetooth/i18n/ca/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/ca/cosmic_applet_bluetooth.ftl index b069b4bf..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/ca/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/ca/cosmic_applet_bluetooth.ftl @@ -1,12 +0,0 @@ -confirm-pin = Si us plau, verifiqueu que el següent PIN coincideix amb el mostrat a { $deviceName } -bluetooth = Bluetooth -unsuccessful = Error d'Emparellament -pairable = Emparellable -try-again = Reintentar -check-device = Si us plau, verifiqueu que { $deviceName } estigui encès, a l'abast i llest per emparellar-se. -other-devices = Altres dispositius Bluetooth -cancel = Cancel·lar -connected = Connectat -confirm = Confirmar -settings = Configuració del Bluetooth... -discoverable = Descobrible diff --git a/cosmic-applet-bluetooth/i18n/da/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/da/cosmic_applet_bluetooth.ftl index 027031b7..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/da/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/da/cosmic_applet_bluetooth.ftl @@ -1,12 +0,0 @@ -cancel = Afbryd -confirm-pin = Bekræft venligst, at følgende pinkode matcher den, der vises på { $deviceName } -bluetooth = Bluetooth -unsuccessful = Parring Mislykkedes -pairable = Parbare -try-again = Prøv Igen -check-device = Sørg for, at { $deviceName } er slået til, inden for rækkevidde og klar til parring. -other-devices = Andre Bluetooth-enheder -connected = Forbundet -confirm = Bekræft -settings = Bluetooth-indstillinger... -discoverable = Synlig diff --git a/cosmic-applet-bluetooth/i18n/de/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/de/cosmic_applet_bluetooth.ftl index 79e52b06..1fa64ced 100644 --- a/cosmic-applet-bluetooth/i18n/de/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/de/cosmic_applet_bluetooth.ftl @@ -1,6 +1,6 @@ bluetooth = Bluetooth other-devices = Andere Bluetooth-Geräte -settings = Bluetooth-Einstellungen ... +settings = Bluetooth-Einstellungen... connected = Verbunden confirm-pin = Bitte bestätige, dass die folgende PIN mit der auf { $deviceName } angezeigten PIN übereinstimmt confirm = Bestätigen diff --git a/cosmic-applet-bluetooth/i18n/el/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/el/cosmic_applet_bluetooth.ftl index 84134b90..98df71af 100644 --- a/cosmic-applet-bluetooth/i18n/el/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/el/cosmic_applet_bluetooth.ftl @@ -1,12 +1,2 @@ cancel = Ακύρωση confirm = Επιβεβαίωση -bluetooth = Bluetooth -confirm-pin = Επιβεβαιώστε ότι το ακόλουθο PIN είναι ίδιο με αυτό που εμφανίζεται στο { $deviceName } -unsuccessful = Ανεπιτυχής σύζευξη -pairable = Συνδέσιμο -try-again = Δοκιμή ξανά -check-device = Βεβαιωθείτε ότι το { $deviceName } είναι ενεργοποιημένο, βρίσκεται εντός εμβέλειας και είναι έτοιμο για σύζευξη. -other-devices = Άλλες συσκευές Bluetooth -connected = Συνδέθηκε -settings = Ρυθμίσεις Bluetooth... -discoverable = Ορατό diff --git a/cosmic-applet-bluetooth/i18n/en-GB/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/en-GB/cosmic_applet_bluetooth.ftl index 9d6e5223..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/en-GB/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/en-GB/cosmic_applet_bluetooth.ftl @@ -1,12 +0,0 @@ -cancel = Cancel -confirm-pin = Please confirm that the following PIN matches the one displayed on { $deviceName } -bluetooth = Bluetooth -unsuccessful = Pairing Unsuccessful -pairable = Pairable -try-again = Try Again -check-device = Make sure { $deviceName } is turned on, in range, and is ready to pair. -other-devices = Other Bluetooth devices -connected = Connected -confirm = Confirm -settings = Bluetooth settings... -discoverable = Discoverable diff --git a/cosmic-applet-bluetooth/i18n/fa/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/fa/cosmic_applet_bluetooth.ftl index 76ff0338..01262e21 100644 --- a/cosmic-applet-bluetooth/i18n/fa/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/fa/cosmic_applet_bluetooth.ftl @@ -2,11 +2,11 @@ bluetooth = بلوتوث other-devices = سایر دستگاه‌های بلوتوث settings = تنظیمات بلوتوث... connected = متصل -confirm-pin = لطفاً تأیید کنید که پین زیر با پین نمایش داده شده در { $deviceName } یکسان است. +confirm-pin = لطفاً تأیید کنید که پین زیر با پین نمایش داده شده در {$deviceName} یکسان است. confirm = تأیید cancel = لغو unsuccessful = جفت‌سازی ناموفق بود -check-device = مطمئن شوید که { $deviceName } روشن، در محدوده و آماده جفت‌سازی است. +check-device = مطمئن شوید که {$deviceName} روشن، در محدوده و آماده جفت‌سازی است. try-again = تلاش دوباره discoverable = قابل شناسایی pairable = قابل جفت‌سازی diff --git a/cosmic-applet-bluetooth/i18n/fil/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/fil/cosmic_applet_bluetooth.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-bluetooth/i18n/gl/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/gl/cosmic_applet_bluetooth.ftl deleted file mode 100644 index c2424610..00000000 --- a/cosmic-applet-bluetooth/i18n/gl/cosmic_applet_bluetooth.ftl +++ /dev/null @@ -1,12 +0,0 @@ -cancel = Cancelar -bluetooth = Bluetooth -other-devices = Outros dispositivos Bluetooth -settings = Axustes Bluetooth… -connected = Conectado -confirm-pin = Por favor, confirme que o seguinte PIN coincide co que se mostra en{ $deviceName } -confirm = Confirmar -unsuccessful = Enparellamento non exitoso -check-device = Asegurate de que { $deviceName } está acendido, dentro do alcance e listo para emparellar. -try-again = Reintentar -discoverable = Atopable -pairable = Emparellable diff --git a/cosmic-applet-bluetooth/i18n/hi/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/hi/cosmic_applet_bluetooth.ftl index f568bb11..ca46bd08 100644 --- a/cosmic-applet-bluetooth/i18n/hi/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/hi/cosmic_applet_bluetooth.ftl @@ -2,11 +2,11 @@ bluetooth = ब्लूटूथ other-devices = अन्य ब्लूटूथ उपकरण settings = ब्लूटूथ सेटिंग्स... connected = जुड़े हुए -confirm-pin = कृपया सुनिश्चित करें कि निम्नलिखित PIN { $deviceName } पर प्रदर्शित PIN से मेल खाता है +confirm-pin = कृपया सुनिश्चित करें कि निम्नलिखित PIN {$deviceName} पर प्रदर्शित PIN से मेल खाता है confirm = पुष्टि करें cancel = रद्द करें unsuccessful = पेयरिंग असफल -check-device = सुनिश्चित करें कि { $deviceName } चालू है, रेंज में है, और पेयर करने के लिए तैयार है। +check-device = सुनिश्चित करें कि {$deviceName} चालू है, रेंज में है, और पेयर करने के लिए तैयार है। try-again = फिर से प्रयास करें discoverable = खोजने योग्य pairable = पेयर करने योग्य diff --git a/cosmic-applet-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl index f12b24b3..ada54d0b 100644 --- a/cosmic-applet-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl @@ -1,7 +1,7 @@ bluetooth = Bluetooth other-devices = Egyéb Bluetooth-eszközök settings = Bluetooth-beállítások… -connected = Kapcsolódva +connected = Csatlakoztatva confirm-pin = Ellenőrizd, hogy a következő PIN-kód megegyezik-e a(z) { $deviceName } eszközön megjelenő PIN-kóddal confirm = Megerősítés cancel = Mégse diff --git a/cosmic-applet-bluetooth/i18n/it/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/it/cosmic_applet_bluetooth.ftl index 4e3d7233..f1ac3a22 100644 --- a/cosmic-applet-bluetooth/i18n/it/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/it/cosmic_applet_bluetooth.ftl @@ -2,11 +2,11 @@ bluetooth = Bluetooth other-devices = Altri dispositivi Bluetooth settings = Impostazioni Bluetooth... connected = Connesso -confirm-pin = Per favore conferma che il seguente PIN corrisponda a quello visualizzato nel dispositivo { $deviceName } +confirm-pin = Per favore conferma che il seguente PIN corrisponda a quello visualizzato nel dispositivo {$deviceName} confirm = Conferma cancel = Annulla unsuccessful = Accoppiamento fallito -check-device = Assicurati che il dispositivo { $deviceName } sia acceso, a portata e pronto per l'accoppiamento. +check-device = Assicurati che il dispositivo {$deviceName} sia acceso, a portata e pronto per l'accoppiamento. try-again = Riprova discoverable = Visibile -pairable = Accoppiabile +pairable = Accoppiabile \ No newline at end of file diff --git a/cosmic-applet-bluetooth/i18n/kab/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/kab/cosmic_applet_bluetooth.ftl index 60232095..b8139437 100644 --- a/cosmic-applet-bluetooth/i18n/kab/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/kab/cosmic_applet_bluetooth.ftl @@ -1,4 +1,4 @@ -cancel = Semmet +cancel = Sefsex connected = Yettwaqqen confirm = Sentem other-devices = Ibenkan-nniḍen n Bluetooth diff --git a/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl index 988f00ca..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl @@ -1,12 +0,0 @@ -cancel = Têk bibe -bluetooth = Bluetooth -connected = Hat girêdan -other-devices = Amûrên Bluetooth ên din -settings = Sazkariyên Bluetooth... -confirm-pin = Tika ye piştrast bike ku PIN a jêrîn bi ya ku li ser { $deviceName } tê xuyakirin re li hev tê -confirm = Bipejirîne -check-device = Piştrast bike ku { $deviceName } çalak e, di hundir rêjeyê de ye, û amade ye ji bo cotkirinê. -try-again = Dîsa hewl bide -discoverable = Dîtbar -pairable = Cotbar -unsuccessful = Cotkirin têkçûyî ye diff --git a/cosmic-applet-bluetooth/i18n/lo/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/lo/cosmic_applet_bluetooth.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-bluetooth/i18n/oc/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/oc/cosmic_applet_bluetooth.ftl index 4676e1c5..0eb4c751 100644 --- a/cosmic-applet-bluetooth/i18n/oc/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/oc/cosmic_applet_bluetooth.ftl @@ -1,2 +1 @@ connected = Connectat -cancel = Anullar diff --git a/cosmic-applet-bluetooth/i18n/sat/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/sat/cosmic_applet_bluetooth.ftl deleted file mode 100644 index 67f522ad..00000000 --- a/cosmic-applet-bluetooth/i18n/sat/cosmic_applet_bluetooth.ftl +++ /dev/null @@ -1 +0,0 @@ -cancel = ᱵᱟᱹᱛᱤᱞ diff --git a/cosmic-applet-bluetooth/i18n/sr/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/sr/cosmic_applet_bluetooth.ftl index b6515b52..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/sr/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/sr/cosmic_applet_bluetooth.ftl @@ -1,12 +0,0 @@ -confirm-pin = Потврдите да се овај ПИН подудара са оним приказаним на { $deviceName } -bluetooth = Блутут -unsuccessful = Неуспешно упаривање -pairable = Упарив -try-again = Покушај поново -check-device = Постарајте се да је { $deviceName } укључен, у домету и спреман за упаривање. -other-devices = Други блутут уређаји -cancel = Откажи -connected = Повезано -confirm = Потврди -settings = Подешавања блутута... -discoverable = Откривљив diff --git a/cosmic-applet-bluetooth/i18n/th/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/th/cosmic_applet_bluetooth.ftl index ffb5afe0..e69de29b 100644 --- a/cosmic-applet-bluetooth/i18n/th/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/th/cosmic_applet_bluetooth.ftl @@ -1,3 +0,0 @@ -connected = เชื่อมต่อแล้ว -confirm = ยืนยัน -cancel = ยกเลิก diff --git a/cosmic-applet-bluetooth/i18n/zh-TW/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/zh-TW/cosmic_applet_bluetooth.ftl index 781a39ec..fa1426a5 100644 --- a/cosmic-applet-bluetooth/i18n/zh-TW/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/zh-TW/cosmic_applet_bluetooth.ftl @@ -1,7 +1,7 @@ bluetooth = 藍牙 other-devices = 其他藍牙裝置 settings = 藍牙設定… -connected = 已連線 +connected = 已經連線 confirm-pin = 請確認此 PIN 碼與 { $deviceName } 上顯示的是否相符 confirm = 確認 cancel = 取消 diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index f9779fc7..2ca95ec5 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -21,10 +21,10 @@ use cosmic::{ widget::{Column, column, container, row}, }, theme, - widget::{button, divider, icon, indeterminate_circular, scrollable, text}, + widget::{button, divider, icon, scrollable, text}, }; use futures::FutureExt; -use std::{collections::HashMap, time::Duration}; +use std::{collections::HashMap, sync::LazyLock, time::Duration}; use tokio::sync::mpsc::Sender; use crate::{ @@ -63,7 +63,6 @@ impl CosmicBluetoothApplet { } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), @@ -76,7 +75,7 @@ enum Message { Token(TokenUpdate), OpenSettings, ToggleBluetooth(bool), - Surface(surface::Action), + Surface(surface::Action), } impl cosmic::Application for CosmicBluetoothApplet { @@ -121,25 +120,20 @@ impl cosmic::Application for CosmicBluetoothApplet { } else { set_discovery(true); - let get_popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); - app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ) - }, - None, - )); + // TODO request update of state maybe + let new_id = window::Id::unique(); + self.popup.replace(new_id); + + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + None, + None, + None, + ); return Task::batch([ - get_popup_task, + get_popup(popup_settings), cosmic::task::future(set_tick(Duration::from_secs(3))) .map(|()| cosmic::Action::App(Message::Ignore)), ]); @@ -151,7 +145,7 @@ impl cosmic::Application for CosmicBluetoothApplet { } Message::BluetoothEvent(e) => match e { BluerEvent::RequestResponse { - req: _, + req, state, err_msg, } => { @@ -304,7 +298,9 @@ impl cosmic::Application for CosmicBluetoothApplet { } } Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } self.update_icon(); @@ -371,12 +367,14 @@ impl cosmic::Application for CosmicBluetoothApplet { ); } BluerDeviceStatus::Paired => {} - BluerDeviceStatus::Connecting - | BluerDeviceStatus::Disconnecting - | BluerDeviceStatus::Pairing => { - row = row.push(indeterminate_circular().size(24.0)); + BluerDeviceStatus::Connecting | BluerDeviceStatus::Disconnecting => { + row = row.push( + icon::from_name("process-working-symbolic") + .size(24) + .symbolic(true), + ); } - BluerDeviceStatus::Disconnected => continue, + BluerDeviceStatus::Disconnected | BluerDeviceStatus::Pairing => continue, } known_bluetooth.push( diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index 3b19c42c..b3648acd 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -149,6 +149,8 @@ pub fn bluetooth_subscription( }, BluerSessionEvent::AgentEvent(e) => BluerEvent::AgentEvent(e), + + _ => return, }; _ = output.send(message).await; @@ -197,7 +199,6 @@ pub enum BluerRequest { } #[derive(Debug, Clone)] -#[allow(dead_code)] pub enum BluerEvent { RequestResponse { req: BluerRequest, @@ -275,9 +276,10 @@ const DEFAULT_DEVICE_ICON: &str = "bluetooth-symbolic"; impl BluerDevice { #[inline(never)] pub async fn from_device(device: &bluer::Device) -> Self { - let (alias, name, is_paired, is_trusted, is_connected, battery_percent, icon) = futures::join!( - device.alias().map(|res| res.ok()), - device.name().map(|res| res.ok().flatten()), + let (mut name, is_paired, is_trusted, is_connected, battery_percent, icon) = futures::join!( + device + .name() + .map(|res| res.ok().flatten().unwrap_or(device.address().to_string())), device.is_paired().map(Result::unwrap_or_default), device.is_trusted().map(Result::unwrap_or_default), device.is_connected().map(Result::unwrap_or_default), @@ -286,11 +288,10 @@ impl BluerDevice { .icon() .map(|res| device_type_to_icon(&res.ok().flatten().unwrap_or_default())) ); - let address_string = device.address().to_string(); - let name = alias - .filter(|name| !name.is_empty() && *name != address_string.replace(':', "-")) - .or(name.filter(|name| !name.is_empty())) - .unwrap_or(address_string); + + if name.is_empty() { + name = device.address().to_string(); + } let status = if is_connected { BluerDeviceStatus::Connected @@ -567,21 +568,22 @@ impl BluerSessionState { tick(&mut interval).await; let new_status = adapter_clone.is_powered().await.unwrap_or_default(); devices = build_device_list(devices, &adapter_clone).await; - let power_changed = new_status != status; - status = new_status; - let state = BluerState { - devices: devices.clone(), - bluetooth_enabled: status, - }; - if power_changed && state.bluetooth_enabled { - for d in &state.devices { - if d.paired_and_trusted() { - _ = req_tx.send(BluerRequest::ConnectDevice(d.address)).await; + if new_status != status { + status = new_status; + let state = BluerState { + devices: devices.clone(), + bluetooth_enabled: status, + }; + if state.bluetooth_enabled { + for d in &state.devices { + if d.paired_and_trusted() { + _ = req_tx.send(BluerRequest::ConnectDevice(d.address)).await; + } } } _ = wake_up_discover_tx.send(()).await; + let _ = tx.send(BluerSessionEvent::ChangesProcessed(state)).await; } - let _ = tx.send(BluerSessionEvent::ChangesProcessed(state)).await; } }); } @@ -672,9 +674,6 @@ impl BluerSessionState { } } - // Always refresh power state from the adapter - // to avoid stale cached is_powered values - is_powered = adapter_clone.is_powered().await.unwrap_or_default(); let _ = tx .send(BluerSessionEvent::ChangesProcessed(BluerState { devices: devices.clone(), @@ -854,7 +853,13 @@ async fn bluer_state(adapter: &Adapter) -> BluerState { #[inline(never)] async fn build_device_list(mut devices: Vec, adapter: &Adapter) -> Vec { - let addrs = adapter.device_addresses().await.unwrap_or_default(); + let addrs: Vec
= adapter + .device_addresses() + .await + .unwrap_or_default() + .into_iter() + .filter(|addr| !devices.iter().any(|d| d.address == *addr)) + .collect(); devices.clear(); if addrs.len() > devices.capacity() { diff --git a/cosmic-applet-input-sources/Cargo.toml b/cosmic-applet-input-sources/Cargo.toml index 004d3b08..92a7daf3 100644 --- a/cosmic-applet-input-sources/Cargo.toml +++ b/cosmic-applet-input-sources/Cargo.toml @@ -1,16 +1,14 @@ [package] name = "cosmic-applet-input-sources" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] -cctk.workspace = true -cosmic-comp-config.workspace = true -futures.workspace = true +cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true +libcosmic.workspace = true rust-embed.workspace = true tokio.workspace = true tracing-log.workspace = true diff --git a/cosmic-applet-input-sources/data/com.system76.CosmicAppletInputSources.desktop b/cosmic-applet-input-sources/data/com.system76.CosmicAppletInputSources.desktop index 73aeccf0..ea0f667b 100644 --- a/cosmic-applet-input-sources/data/com.system76.CosmicAppletInputSources.desktop +++ b/cosmic-applet-input-sources/data/com.system76.CosmicAppletInputSources.desktop @@ -12,5 +12,4 @@ NoDisplay=true X-CosmicApplet=true X-CosmicShrinkable=true X-CosmicHoverPopup=Auto -X-HostWaylandDisplay=true X-OverflowPriority=10 diff --git a/cosmic-applet-input-sources/i18n/ca/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/ca/cosmic_applet_input_sources.ftl index 12a2de28..e69de29b 100644 --- a/cosmic-applet-input-sources/i18n/ca/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/ca/cosmic_applet_input_sources.ftl @@ -1,2 +0,0 @@ -show-keyboard-layout = Mostra la disposició de teclat... -keyboard-settings = Configuració de teclat... diff --git a/cosmic-applet-input-sources/i18n/da/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/da/cosmic_applet_input_sources.ftl index 9759ea2a..e69de29b 100644 --- a/cosmic-applet-input-sources/i18n/da/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/da/cosmic_applet_input_sources.ftl @@ -1,2 +0,0 @@ -show-keyboard-layout = Vis Tastaturopsætning... -keyboard-settings = Tastaturindstillinger... diff --git a/cosmic-applet-input-sources/i18n/de/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/de/cosmic_applet_input_sources.ftl index ddc457d7..6be93fc6 100644 --- a/cosmic-applet-input-sources/i18n/de/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/de/cosmic_applet_input_sources.ftl @@ -1,2 +1,2 @@ -show-keyboard-layout = Tastaturbelegung anzeigen ... -keyboard-settings = Tastatureinstellungen ... +show-keyboard-layout = Tastaturbelegung anzeigen... +keyboard-settings = Tastatureinstellungen... diff --git a/cosmic-applet-input-sources/i18n/el/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/el/cosmic_applet_input_sources.ftl index 546be28d..e69de29b 100644 --- a/cosmic-applet-input-sources/i18n/el/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/el/cosmic_applet_input_sources.ftl @@ -1,2 +0,0 @@ -show-keyboard-layout = Εμφάνιση διάταξης πληκτρολογίου... -keyboard-settings = Ρυθμίσεις πληκτρολογίου... diff --git a/cosmic-applet-input-sources/i18n/fil/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/fil/cosmic_applet_input_sources.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-input-sources/i18n/gl/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/gl/cosmic_applet_input_sources.ftl deleted file mode 100644 index 85e8072c..00000000 --- a/cosmic-applet-input-sources/i18n/gl/cosmic_applet_input_sources.ftl +++ /dev/null @@ -1,2 +0,0 @@ -show-keyboard-layout = Mostrar a disposición do teclado... -keyboard-settings = Axustes do teclado... diff --git a/cosmic-applet-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl index 737324c5..e69de29b 100644 --- a/cosmic-applet-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl @@ -1,2 +0,0 @@ -show-keyboard-layout = Awaya kilîtdankê nîşan bide... -keyboard-settings = Sazkariyên kilîtdankê... diff --git a/cosmic-applet-input-sources/i18n/lo/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/lo/cosmic_applet_input_sources.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-input-sources/i18n/sat/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/sat/cosmic_applet_input_sources.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-input-sources/i18n/sr/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/sr/cosmic_applet_input_sources.ftl index 4d552b47..e69de29b 100644 --- a/cosmic-applet-input-sources/i18n/sr/cosmic_applet_input_sources.ftl +++ b/cosmic-applet-input-sources/i18n/sr/cosmic_applet_input_sources.ftl @@ -1,2 +0,0 @@ -show-keyboard-layout = Прикажи распоред тастатуре... -keyboard-settings = Подешавања тастатуре... diff --git a/cosmic-applet-input-sources/src/lib.rs b/cosmic-applet-input-sources/src/lib.rs index d22d3e7b..93e84283 100644 --- a/cosmic-applet-input-sources/src/lib.rs +++ b/cosmic-applet-input-sources/src/lib.rs @@ -3,59 +3,37 @@ mod localize; -use cctk::{ - cosmic_protocols::keyboard_layout::v1::client::zcosmic_keyboard_layout_v1::ZcosmicKeyboardLayoutV1, - wayland_client::{Connection, Proxy, backend::Backend}, -}; +use cosmic::iced::{Alignment, Length}; use cosmic::{ app, app::Core, applet::{self}, + cosmic_config::{self, ConfigSet, CosmicConfigEntry}, cosmic_theme::Spacing, iced::Subscription, - iced::core::window, iced::{ - self, Rectangle, Task, - event::wayland::{Event as WaylandEvent, OutputEvent}, + Rectangle, Task, platform_specific::shell::commands::popup::{destroy_popup, get_popup}, + widget::{column, row}, window::Id, }, + iced::{core::window, runtime::Appearance}, prelude::*, surface, theme, widget::{ self, autosize, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, + space, }, }; -use cosmic_comp_config::{CosmicCompConfig, XkbConfig}; -use std::{ - os::unix::{ - io::{FromRawFd, RawFd}, - net::UnixStream, - }, - sync::LazyLock, -}; +use cosmic_comp_config::CosmicCompConfig; +use std::sync::LazyLock; use xkb_data::KeyboardLayout; -mod wayland; - static AUTOSIZE_MAIN_ID: LazyLock = LazyLock::new(|| widget::Id::new("autosize-main")); pub const ID: &str = "com.system76.CosmicAppletInputSources"; pub fn run() -> cosmic::iced::Result { - let socket = std::env::var("X_PRIVILEGED_WAYLAND_SOCKET") - .ok() - .and_then(|fd| { - fd.parse::() - .ok() - .map(|fd| unsafe { UnixStream::from_raw_fd(fd) }) - }); - let wayland_connection = if let Some(socket) = socket { - Some(Connection::from_socket(socket).unwrap()) - } else { - None - }; - localize::localize(); let layouts = match xkb_data::all_keyboard_layouts() { @@ -66,8 +44,27 @@ pub fn run() -> cosmic::iced::Result { } }; + let (comp_config_handler, comp_config) = + match cosmic_config::Config::new("com.system76.CosmicComp", CosmicCompConfig::VERSION) { + Ok(config_handler) => { + let config = match CosmicCompConfig::get_entry(&config_handler) { + Ok(ok) => ok, + Err((errs, config)) => { + tracing::error!("errors loading config: {:?}", errs); + config + } + }; + (Some(config_handler), config) + } + Err(err) => { + tracing::error!("failed to create config handler: {}", err); + (None, CosmicCompConfig::default()) + } + }; + cosmic::applet::run::(Flags { - wayland_connection, + comp_config, + comp_config_handler, layouts: layouts.layout_list.layout, }) } @@ -82,13 +79,12 @@ pub struct ActiveLayout { pub struct Window { core: Core, popup: Option, + comp_config: CosmicCompConfig, + comp_config_handler: Option, layouts: Vec, active_layouts: Vec, rectangle_tracker: Option>, rectangle: Rectangle, - wayland_connection: Option, - keyboard_layout: Option, - current_layout: usize, } #[derive(Clone, Debug)] @@ -98,15 +94,14 @@ pub enum Message { CompConfig(Box), SetActiveLayout(usize), KeyboardSettings, - Surface(surface::Action), + Surface(surface::Action), Rectangle(RectangleUpdate), - WaylandConnection(Backend), - Wayland(wayland::Event), } #[derive(Debug)] pub struct Flags { - wayland_connection: Option, + pub comp_config: CosmicCompConfig, + pub comp_config_handler: Option, pub layouts: Vec, } @@ -127,15 +122,14 @@ impl cosmic::Application for Window { fn init(core: Core, flags: Self::Flags) -> (Self, app::Task) { let window = Window { + comp_config_handler: flags.comp_config_handler, layouts: flags.layouts, core, popup: None, + comp_config: flags.comp_config, active_layouts: Vec::new(), rectangle_tracker: None, rectangle: Rectangle::default(), - wayland_connection: flags.wayland_connection, - keyboard_layout: None, - current_layout: 0, }; (window, Task::none()) } @@ -148,24 +142,19 @@ impl cosmic::Application for Window { match message { Message::TogglePopup => { return if let Some(p) = self.popup.take() { - return crate::surface::surface_task(crate::surface::action::destroy_popup(p)); + destroy_popup(p) } else { - return crate::surface::surface_task(crate::surface::action::app_popup( - |_| Default::default(), - |app: &mut Window| { - let new_id = Id::unique(); - app.popup.replace(new_id); - let popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - popup_settings - }, + let new_id = Id::unique(); + self.popup.replace(new_id); + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, None, - )); + None, + None, + ); + + get_popup(popup_settings) }; } Message::PopupClosed(id) => { @@ -174,7 +163,8 @@ impl cosmic::Application for Window { } } Message::CompConfig(config) => { - self.active_layouts = self.update_xkb(&config.xkb_config); + self.comp_config = *config; + self.active_layouts = self.update_xkb(); } Message::KeyboardSettings => { let mut cmd = std::process::Command::new("cosmic-settings"); @@ -182,15 +172,38 @@ impl cosmic::Application for Window { tokio::spawn(cosmic::process::spawn(cmd)); } Message::SetActiveLayout(pos) => { - if let Some(keyboard_layout) = &self.keyboard_layout { - keyboard_layout.set_group(pos as u32); - if let Some(backend) = keyboard_layout.backend().upgrade() { - let _ = backend.flush(); + if pos == 0 { + return Task::none(); + } + + self.active_layouts.swap(0, pos); + let mut new_layout = String::new(); + let mut new_variant = String::new(); + + for layout in &self.active_layouts { + new_layout.push_str(&layout.layout); + new_layout.push(','); + new_variant.push_str(&layout.variant); + new_variant.push(','); + } + + let _excess_comma = new_layout.pop(); + let _excess_comma = new_variant.pop(); + + self.comp_config.xkb_config.layout = new_layout; + self.comp_config.xkb_config.variant = new_variant; + if let Some(comp_config_handler) = &self.comp_config_handler { + if let Err(err) = + comp_config_handler.set("xkb_config", &self.comp_config.xkb_config) + { + tracing::error!("Failed to set config 'xkb_config' {err}"); } } } Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } Message::Rectangle(u) => match u { RectangleUpdate::Rectangle(r) => { @@ -200,26 +213,13 @@ impl cosmic::Application for Window { self.rectangle_tracker = Some(tracker); } }, - Message::WaylandConnection(backend) => { - if self.wayland_connection.is_none() { - self.wayland_connection = Some(Connection::from_backend(backend)); - } - } - Message::Wayland(w) => match w { - wayland::Event::KeyboardLayout(keyboard_layout) => { - self.keyboard_layout = Some(keyboard_layout); - } - wayland::Event::Group(group) => { - self.current_layout = group as usize; - } - }, } Task::none() } fn view(&self) -> Element<'_, Self::Message> { - let applet_text = if let Some(l) = self.active_layouts.get(self.current_layout) { + let applet_text = if let Some(l) = self.active_layouts.first() { if !l.variant.is_empty() { format!("{} ({})", l.layout, l.variant) } else { @@ -252,13 +252,8 @@ impl cosmic::Application for Window { let mut content_list = widget::column::with_capacity(4 + self.active_layouts.len()).padding([8, 0]); for (id, layout) in self.active_layouts.iter().enumerate() { - let font = if id == self.current_layout { - cosmic::font::bold() - } else { - cosmic::font::default() - }; let group = widget::column::with_capacity(2) - .push(widget::text::body(layout.description.as_str()).font(font)) + .push(widget::text::body(layout.description.as_str())) .push(widget::text::caption(layout.layout.as_str())); content_list = content_list .push(applet::menu_button(group).on_press(Message::SetActiveLayout(id))); @@ -279,7 +274,7 @@ impl cosmic::Application for Window { } fn subscription(&self) -> Subscription { - let mut subscriptions = vec![ + Subscription::batch(vec![ rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)), self.core .watch_config("com.system76.CosmicComp") @@ -293,23 +288,7 @@ impl cosmic::Application for Window { } Message::CompConfig(Box::new(update.config)) }), - ]; - subscriptions.push(if let Some(connection) = &self.wayland_connection { - wayland::subscription(connection.clone()).map(Message::Wayland) - } else { - iced::event::listen_with(|evt, _, _| match evt { - iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(evt)) => { - if let WaylandEvent::Output(OutputEvent::Created(_), output) = evt { - if let Some(backend) = output.backend().upgrade() { - return Some(Message::WaylandConnection(backend)); - } - } - None - } - _ => None, - }) - }); - Subscription::batch(subscriptions) + ]) } fn style(&self) -> Option { @@ -317,8 +296,9 @@ impl cosmic::Application for Window { } } impl Window { - fn update_xkb(&self, xkb: &XkbConfig) -> Vec { + fn update_xkb(&self) -> Vec { let mut active_layouts = Vec::new(); + let xkb = &self.comp_config.xkb_config; let layouts = xkb.layout.split_terminator(','); diff --git a/cosmic-applet-input-sources/src/wayland.rs b/cosmic-applet-input-sources/src/wayland.rs deleted file mode 100644 index 7bee2245..00000000 --- a/cosmic-applet-input-sources/src/wayland.rs +++ /dev/null @@ -1,157 +0,0 @@ -use cctk::{ - cosmic_protocols::keyboard_layout::v1::client::zcosmic_keyboard_layout_v1::ZcosmicKeyboardLayoutV1, - keyboard_layout::{KeyboardLayoutHandler, KeyboardLayoutState}, - sctk::{ - self, - registry::{ProvidesRegistryState, RegistryState}, - seat::{Capability, SeatHandler, SeatState}, - }, - wayland_client::{ - Connection, QueueHandle, delegate_noop, - globals::registry_queue_init, - protocol::{wl_keyboard, wl_seat}, - }, -}; -use cosmic::iced; -use futures::{SinkExt, channel::mpsc, executor::block_on}; -use std::{hash::Hash, thread}; - -#[derive(Clone, Debug)] -pub enum Event { - KeyboardLayout(ZcosmicKeyboardLayoutV1), - Group(usize), -} - -pub fn subscription(connection: Connection) -> iced::Subscription { - #[derive(Clone)] - struct WaylandSubscription(Connection); - impl Hash for WaylandSubscription { - fn hash(&self, state: &mut H) { - self.0.backend().display_id().hash(state); - } - } - iced::Subscription::run_with( - WaylandSubscription(connection), - |WaylandSubscription(connection)| { - let connection = connection.clone(); - iced::stream::channel(8, move |sender| async move { - thread::spawn(move || thread(connection, sender)); - }) - }, - ) -} - -struct Keyboard { - seat: wl_seat::WlSeat, - keyboard_layout: ZcosmicKeyboardLayoutV1, -} - -impl Drop for Keyboard { - fn drop(&mut self) { - self.keyboard_layout.destroy(); - } -} - -struct AppData { - seat_state: SeatState, - registry_state: RegistryState, - keyboard_layout_state: KeyboardLayoutState, - keyboard: Option, - sender: mpsc::Sender, -} - -impl KeyboardLayoutHandler for AppData { - fn group( - &mut self, - _conn: &Connection, - _qh: &QueueHandle, - _keyboard: &wl_keyboard::WlKeyboard, - _keyboard_layout: &ZcosmicKeyboardLayoutV1, - group: u32, - ) { - let _ = block_on(self.sender.send(Event::Group(group as usize))); - } -} - -impl ProvidesRegistryState for AppData { - fn registry(&mut self) -> &mut RegistryState { - &mut self.registry_state - } - - sctk::registry_handlers![SeatState,]; -} - -impl SeatHandler for AppData { - fn seat_state(&mut self) -> &mut SeatState { - &mut self.seat_state - } - - fn new_seat(&mut self, _: &Connection, _: &QueueHandle, _: wl_seat::WlSeat) {} - - fn new_capability( - &mut self, - _conn: &Connection, - qh: &QueueHandle, - seat: wl_seat::WlSeat, - capability: Capability, - ) { - if capability == Capability::Keyboard && self.keyboard.is_none() { - let keyboard = seat.get_keyboard(qh, ()); - let keyboard_layout = self - .keyboard_layout_state - .get_keyboard_layout(&keyboard, qh); - keyboard.release(); - - if let Some(keyboard_layout) = keyboard_layout { - let _ = block_on( - self.sender - .send(Event::KeyboardLayout(keyboard_layout.clone())), - ); - self.keyboard = Some(Keyboard { - seat, - keyboard_layout, - }); - } else { - keyboard.release(); - } - } - } - - fn remove_capability( - &mut self, - _conn: &Connection, - _: &QueueHandle, - seat: wl_seat::WlSeat, - _capability: Capability, - ) { - self.keyboard.take_if(|x| x.seat == seat); - } - - fn remove_seat(&mut self, _: &Connection, _: &QueueHandle, seat: wl_seat::WlSeat) { - self.keyboard.take_if(|x| x.seat == seat); - } -} - -fn thread(conn: Connection, sender: mpsc::Sender) { - let (globals, mut event_queue) = registry_queue_init(&conn).unwrap(); - let qh = event_queue.handle(); - let registry_state = RegistryState::new(&globals); - let seat_state = SeatState::new(&globals, &qh); - let keyboard_layout_state = KeyboardLayoutState::new(®istry_state, &qh); - - let mut app_data = AppData { - seat_state, - registry_state, - keyboard_layout_state, - keyboard: None, - sender, - }; - loop { - event_queue.blocking_dispatch(&mut app_data).unwrap(); - } -} - -sctk::delegate_registry!(AppData); -sctk::delegate_seat!(AppData); -cctk::delegate_keyboard_layout!(AppData); -delegate_noop!(AppData: ignore wl_keyboard::WlKeyboard); diff --git a/cosmic-applet-minimize/Cargo.toml b/cosmic-applet-minimize/Cargo.toml index e3cc52da..783be11b 100644 --- a/cosmic-applet-minimize/Cargo.toml +++ b/cosmic-applet-minimize/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-minimize" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -9,7 +9,7 @@ anyhow.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true image = { version = "0.25.9", default-features = false } -cosmic.workspace = true +libcosmic.workspace = true memmap2 = "0.9.10" rust-embed.workspace = true rustix.workspace = true diff --git a/cosmic-applet-minimize/src/lib.rs b/cosmic-applet-minimize/src/lib.rs index 7683630c..e40a7551 100644 --- a/cosmic-applet-minimize/src/lib.rs +++ b/cosmic-applet-minimize/src/lib.rs @@ -126,7 +126,7 @@ enum Message { Closed(window::Id), OpenOverflowPopup, CloseOverflowPopup, - Surface(surface::Action), + Surface(surface::Action), } impl cosmic::Application for Minimize { @@ -248,53 +248,47 @@ impl cosmic::Application for Minimize { } Message::OpenOverflowPopup => { if let Some(id) = self.overflow_popup.take() { - return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup( - id, - )); + return destroy_popup(id); } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = window::Id::unique(); - let pos = app.max_icon_count().unwrap_or_default(); + let new_id = window::Id::unique(); + let pos = self.max_icon_count().unwrap_or_default(); - app.overflow_popup = Some(new_id); - let icon_size = app.core.applet.suggested_size(true).0 as u32 - + 2 * app.core.applet.suggested_padding(true).1 as u32; - let spacing = app.core.system_theme().cosmic().space_xxs() as u32; - let major_axis_len = - (icon_size + spacing) * (pos.saturating_sub(1) as u32); - let rectangle = match app.core.applet.anchor { - PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle { - x: major_axis_len as i32, - y: 0, - width: icon_size as i32, - height: icon_size as i32, - }, - PanelAnchor::Left | PanelAnchor::Right => iced::Rectangle { - x: 0, - y: major_axis_len as i32, - width: icon_size as i32, - height: icon_size as i32, - }, - }; - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - popup_settings.positioner.anchor_rect = rectangle; - popup_settings + self.overflow_popup = Some(new_id); + let icon_size = self.core.applet.suggested_size(true).0 as u32 + + 2 * self.core.applet.suggested_padding(true).1 as u32; + let spacing = self.core.system_theme().cosmic().space_xxs() as u32; + let major_axis_len = (icon_size + spacing) * (pos.saturating_sub(1) as u32); + let rectangle = match self.core.applet.anchor { + PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle { + x: major_axis_len as i32, + y: 0, + width: icon_size as i32, + height: icon_size as i32, }, + PanelAnchor::Left | PanelAnchor::Right => iced::Rectangle { + x: 0, + y: major_axis_len as i32, + width: icon_size as i32, + height: icon_size as i32, + }, + }; + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, None, - )); + None, + None, + ); + popup_settings.positioner.anchor_rect = rectangle; + + return get_popup(popup_settings); } } Message::CloseOverflowPopup => todo!(), Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } Task::none() @@ -322,7 +316,7 @@ impl cosmic::Application for Minimize { } else { (cross_padding, major_padding) }; - let _theme = self.core.system_theme().cosmic(); + let theme = self.core.system_theme().cosmic(); let icon_buttons = self.apps[..max_icon_count].iter().map(|app| { self.core .applet @@ -426,7 +420,7 @@ impl cosmic::Application for Minimize { (cross_padding, major_padding) }; let theme = self.core.system_theme().cosmic(); - let _space_xxs = theme.space_xxs(); + let space_xxs = theme.space_xxs(); let icon_buttons = self.apps[max_icon_count..].iter().map(|app| { tooltip( Element::from(crate::window_image::WindowImage::new( diff --git a/cosmic-applet-minimize/src/wayland_handler.rs b/cosmic-applet-minimize/src/wayland_handler.rs index 562693e2..bf2eae30 100644 --- a/cosmic-applet-minimize/src/wayland_handler.rs +++ b/cosmic-applet-minimize/src/wayland_handler.rs @@ -121,7 +121,6 @@ struct AppData { toplevel_info_state: ToplevelInfoState, toplevel_manager_state: ToplevelManagerState, seat_state: SeatState, - captured_toplevels: std::collections::HashSet, } struct CaptureData { @@ -352,36 +351,6 @@ impl AppData { } }); } - - fn handle_toplevel(&mut self, toplevel: &ExtForeignToplevelHandleV1, is_new: bool) { - let Some(info) = self.toplevel_info_state.info(toplevel) else { - return; - }; - if info - .state - .contains(&zcosmic_toplevel_handle_v1::State::Minimized) - { - // Capture a thumbnail once, on the transition into minimized. - if self.captured_toplevels.insert(toplevel.clone()) { - self.send_image(toplevel.clone()); - } - let update = if is_new { - ToplevelUpdate::Add(info.clone()) - } else { - ToplevelUpdate::Update(info.clone()) - }; - let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel(update))); - } else { - self.remove_toplevel(toplevel); - } - } - - fn remove_toplevel(&mut self, toplevel: &ExtForeignToplevelHandleV1) { - self.captured_toplevels.remove(toplevel); - let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( - ToplevelUpdate::Remove(toplevel.clone()), - ))); - } } impl ToplevelInfoHandler for AppData { @@ -395,7 +364,23 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - self.handle_toplevel(toplevel, true); + if let Some(info) = self.toplevel_info_state.info(toplevel) { + if info + .state + .contains(&zcosmic_toplevel_handle_v1::State::Minimized) + { + // spawn thread for sending the image + self.send_image(toplevel.clone()); + let _ = futures::executor::block_on( + self.tx + .send(WaylandUpdate::Toplevel(ToplevelUpdate::Add(info.clone()))), + ); + } else { + let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( + ToplevelUpdate::Remove(toplevel.clone()), + ))); + } + } } fn update_toplevel( @@ -404,7 +389,21 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - self.handle_toplevel(toplevel, false); + if let Some(info) = self.toplevel_info_state.info(toplevel) { + if info + .state + .contains(&zcosmic_toplevel_handle_v1::State::Minimized) + { + self.send_image(toplevel.clone()); + let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( + ToplevelUpdate::Update(info.clone()), + ))); + } else { + let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( + ToplevelUpdate::Remove(toplevel.clone()), + ))); + } + } } fn toplevel_closed( @@ -413,7 +412,9 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - self.remove_toplevel(toplevel); + let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( + ToplevelUpdate::Remove(toplevel.clone()), + ))); } } @@ -481,7 +482,6 @@ pub(crate) fn wayland_handler( toplevel_manager_state: ToplevelManagerState::new(®istry_state, &qh), queue_handle: qh, registry_state, - captured_toplevels: std::collections::HashSet::new(), }; loop { diff --git a/cosmic-applet-network/Cargo.toml b/cosmic-applet-network/Cargo.toml index c1d4220f..659dd076 100644 --- a/cosmic-applet-network/Cargo.toml +++ b/cosmic-applet-network/Cargo.toml @@ -1,16 +1,18 @@ [package] name = "cosmic-applet-network" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-or-later" [dependencies] +anyhow.workspace = true async-fn-stream = "0.3" +cosmic-dbus-networkmanager = { git = "https://github.com/pop-os/dbus-settings-bindings" } futures.workspace = true futures-util.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic = { workspace = true, features = [ +libcosmic = { workspace = true, features = [ "applet", "applet-token", "tokio", @@ -23,7 +25,17 @@ tokio.workspace = true tracing-log.workspace = true tracing-subscriber.workspace = true tracing.workspace = true +zbus.workspace = true +nm-secret-agent-manager = { git = "https://github.com/pop-os/dbus-settings-bindings/" } indexmap = "2.13.0" secure-string = "0.3.0" uuid = { version = "1.21.0", features = ["v4"] } -nmrs = "3.5.2" + + +[dependencies.cosmic-settings-network-manager-subscription] +git = "https://github.com/pop-os/cosmic-settings/" +# path = "../../cosmic-settings/subscriptions/network-manager" + +[dependencies.cosmic-settings-airplane-mode-subscription] +git = "https://github.com/pop-os/cosmic-settings/" +# path = "../../cosmic-settings/subscriptions/airplane-mode" diff --git a/cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf b/cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf deleted file mode 100644 index 8e98cedb..00000000 --- a/cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/cosmic-applet-network/i18n/ca/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/ca/cosmic_applet_network.ftl index ae3bd5dd..e69de29b 100644 --- a/cosmic-applet-network/i18n/ca/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/ca/cosmic_applet_network.ftl @@ -1,4 +0,0 @@ -cancel = Cancel·lar -connected = Connectat -wifi = Wi-Fi -identity = Identitat diff --git a/cosmic-applet-network/i18n/da/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/da/cosmic_applet_network.ftl index bd21c41f..e69de29b 100644 --- a/cosmic-applet-network/i18n/da/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/da/cosmic_applet_network.ftl @@ -1,24 +0,0 @@ -cancel = Afbryd -connected = Forbundet -connect = Opret forbindelse -wifi = Wi-Fi -identity = Identitet -network = Netværk -check-wifi-connection = Sørg for, at Wi-Fi er forbundet til internettet og adgangskoden er korrekt -reset = Nulstil -visible-wireless-networks = Synlige trådløse netværk -enter-password = Indtast adgangskoden eller krypteringsnøglen -ipv6 = IPv6-adresse -airplane-mode-on = Flytilstand er slået til -connecting = Forbinder -airplane-mode = Flytilstand -ipv4 = IPv4-adresse -unable-to-connect = Ude af stand til at forbinde til netværk -turn-off-airplane-mode = Slå fra, for at aktivere Wi-Fi, Bluetooth og mobilt bredbånd. -vpn-connections = VPN-forbindelser -mac = MAC -router-wps-button = Du kan også forbinde ved tryk på knappen "WPS" på routeren -settings = Netværksindstillinger... -megabits-per-second = Mbps -gigabits-per-second = Gbps -terabits-per-second = Tbps diff --git a/cosmic-applet-network/i18n/de/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/de/cosmic_applet_network.ftl index fe267462..0a913c0b 100644 --- a/cosmic-applet-network/i18n/de/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/de/cosmic_applet_network.ftl @@ -12,7 +12,7 @@ connected = Verbunden connecting = Wird verbunden connect = Verbinden cancel = Abbrechen -settings = Netzwerkeinstellungen ... +settings = Netzwerkeinstellungen... visible-wireless-networks = Sichtbare Drahtlosnetzwerke enter-password = Gib das Passwort oder den Verschlüsselungsschlüssel ein router-wps-button = Du kannst dich auch verbinden, indem du die Taste „WPS” am Router drückst diff --git a/cosmic-applet-network/i18n/el/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/el/cosmic_applet_network.ftl index 8eac3a7a..c7ed802d 100644 --- a/cosmic-applet-network/i18n/el/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/el/cosmic_applet_network.ftl @@ -1,24 +1 @@ cancel = Ακύρωση -connect = Σύνδεση -network = Δίκτυο -check-wifi-connection = Βεβαιωθείτε ότι το Wi-Fi είναι συνδεδεμένο στο διαδίκτυο και ότι ο κωδικός πρόσβασης είναι σωστός -reset = Επαναφορά -visible-wireless-networks = Ορατά ασύρματα δίκτυα -enter-password = Εισαγάγετε τον κωδικό πρόσβασης ή το κλειδί κρυπτογράφησης -ipv6 = Διεύθυνση IPv6 -airplane-mode-on = Η λειτουργία πτήσης είναι ενεργή -connecting = Σύνδεση -airplane-mode = Λειτουργία πτήσης -wifi = Wi-Fi -ipv4 = Διεύθυνση IPv4 -identity = Ταυτότητα -unable-to-connect = Δεν είναι δυνατή η σύνδεση στο δίκτυο -turn-off-airplane-mode = Απενεργοποιήστε τη για ενεργοποίηση του Wi-Fi, του Bluetooth και της κινητής ευρυζωνικής σύνδεσης. -connected = Συνδέθηκε -vpn-connections = Συνδέσεις VPN -mac = MAC -router-wps-button = Μπορείτε επίσης να συνδεθείτε πατώντας το κουμπί «WPS» του δρομολογητή -settings = Ρυθμίσεις δικτύου... -megabits-per-second = Mbps -gigabits-per-second = Gbps -terabits-per-second = Tbps diff --git a/cosmic-applet-network/i18n/en-GB/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/en-GB/cosmic_applet_network.ftl index 72b1d8d4..e69de29b 100644 --- a/cosmic-applet-network/i18n/en-GB/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/en-GB/cosmic_applet_network.ftl @@ -1,2 +0,0 @@ -cancel = Cancel -connected = Connected diff --git a/cosmic-applet-network/i18n/fil/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/fil/cosmic_applet_network.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-network/i18n/fr/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/fr/cosmic_applet_network.ftl index 427f8e96..f2c0025d 100644 --- a/cosmic-applet-network/i18n/fr/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/fr/cosmic_applet_network.ftl @@ -9,7 +9,7 @@ mac = MAC megabits-per-second = Mbps connected = Connecté connecting = Connexion -connect = Se connecter +connect = Connecter cancel = Annuler settings = Paramètres réseaux... visible-wireless-networks = Réseaux Wi-Fi disponibles diff --git a/cosmic-applet-network/i18n/gl/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/gl/cosmic_applet_network.ftl deleted file mode 100644 index 33d76626..00000000 --- a/cosmic-applet-network/i18n/gl/cosmic_applet_network.ftl +++ /dev/null @@ -1,24 +0,0 @@ -cancel = Cancelar -connected = Conectado -connect = Conectar -identity = Identidade -wifi = Wi-Fi -network = Rede -airplane-mode = Modo avión -airplane-mode-on = O modo avión está activo -turn-off-airplane-mode = Desactívao para activar a wifi, o Bluetooth e a banda larga móbil. -ipv4 = Dirección IPv4 -ipv6 = Dirección IPv6 -mac = MAC -megabits-per-second = Mbps -gigabits-per-second = Gbps -terabits-per-second = Tbps -connecting = Conectando -settings = Axustes da rede... -visible-wireless-networks = Redes sen fíos visibles -vpn-connections = Conexións VPN -enter-password = Introduce o contrasinal ou a chave de cifrado -router-wps-button = Tamén podes conectarte premendo o botón "WPS" do router -unable-to-connect = Non se puido conectar á rede -check-wifi-connection = Asegúrate de que a wifi está conectada a Internet e de que o contrasinal é correcto -reset = Restablecer diff --git a/cosmic-applet-network/i18n/hu/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/hu/cosmic_applet_network.ftl index 4ad41d3f..e9a61812 100644 --- a/cosmic-applet-network/i18n/hu/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/hu/cosmic_applet_network.ftl @@ -1,16 +1,16 @@ network = Hálózat airplane-mode = Repülőgép-üzemmód airplane-mode-on = A repülőgép-üzemmód be van kapcsolva -turn-off-airplane-mode = Kapcsold ki a Wi-Fi, Bluetooth és mobil széles sáv engedélyezéséhez. +turn-off-airplane-mode = Kapcsold ki a Wi-Fi, Bluetooth és mobil szélessáv engedélyezéséhez. wifi = Wi-Fi identity = Azonosító ipv4 = IPv4-cím ipv6 = IPv6-cím mac = MAC megabits-per-second = Mbps -connected = Kapcsolódva -connecting = Kapcsolódás -connect = Kapcsolódás +connected = Csatlakoztatva +connecting = Csatlakozás… +connect = Csatlakozás cancel = Mégse settings = Hálózati beállítások… visible-wireless-networks = Látható vezeték nélküli hálózatok diff --git a/cosmic-applet-network/i18n/kab/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/kab/cosmic_applet_network.ftl index 8bc6a315..68ce8e75 100644 --- a/cosmic-applet-network/i18n/kab/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/kab/cosmic_applet_network.ftl @@ -1,4 +1,4 @@ -cancel = Semmet +cancel = Sefsex connect = Qqen identity = Tamagit wifi = Wi-Fi diff --git a/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl index 3dbb0266..e69de29b 100644 --- a/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl @@ -1,24 +0,0 @@ -cancel = Têk bibe -connect = Girê bide -connected = Hat girêdan -network = Tor -airplane-mode = Awaya balafirê -airplane-mode-on = Awaya balafirê vekirî ye -turn-off-airplane-mode = Ji bo çalakirina Wi-Fi, Bluetooth û torên mobayîl, awaya balafirê bigire. -wifi = Wi-Fi -identity = Nasname -ipv4 = IPv4 -ipv6 = IPv6 -mac = MAC -megabits-per-second = Mbps -gigabits-per-second = Gbps -terabits-per-second = Tbps -connecting = Tê girêdan -settings = Sazkariyên torê... -visible-wireless-networks = Torên bêtêl ên xuya -vpn-connections = Girêdanên VPN -enter-password = Borînpeyvê yan jî kilîtê şîfrekirinê têxîne -router-wps-button = Tu dikarî bi pêlkirina bişkoka "WPS" ya li ser routerê jî girê bidî -unable-to-connect = Nikare bi torê ve were girêdan -check-wifi-connection = Piştrast bike ku Wi-Fi bi înternetê ve girêdayî ye û borînpeyv rast e -reset = Ji nû ve saz bike diff --git a/cosmic-applet-network/i18n/lo/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/lo/cosmic_applet_network.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-network/i18n/oc/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/oc/cosmic_applet_network.ftl index 45cd8472..fafd4068 100644 --- a/cosmic-applet-network/i18n/oc/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/oc/cosmic_applet_network.ftl @@ -1,5 +1,3 @@ identity = Identitat connected = Connectat connect = Connectar -cancel = Anullar -network = Ret diff --git a/cosmic-applet-network/i18n/sat/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/sat/cosmic_applet_network.ftl deleted file mode 100644 index 67f522ad..00000000 --- a/cosmic-applet-network/i18n/sat/cosmic_applet_network.ftl +++ /dev/null @@ -1 +0,0 @@ -cancel = ᱵᱟᱹᱛᱤᱞ diff --git a/cosmic-applet-network/i18n/sr/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/sr/cosmic_applet_network.ftl index b79b0ddd..e69de29b 100644 --- a/cosmic-applet-network/i18n/sr/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/sr/cosmic_applet_network.ftl @@ -1,24 +0,0 @@ -cancel = Откажи -connected = Повезано -connect = Повежи -identity = Идентитет -wifi = Бежична -check-wifi-connection = Уверите се да је бежична мрежа повезана са интернетом и да је лозинка тачна -reset = Врати -visible-wireless-networks = Видљиве бежичне мреже -enter-password = Унесите лозинку или кључ за шифровање -ipv6 = ИПв6 адреса -airplane-mode-on = Авионски режим је укључен -connecting = Повезује се -airplane-mode = Авио режим -ipv4 = ИПв4 адреса -unable-to-connect = Немогуће повезати се са мрежом -turn-off-airplane-mode = Искључите да бисте омогућили Блутут, бежичну и мобилни интернет. -network = Мрежа -vpn-connections = ВПН везе -mac = МАК -router-wps-button = Такође се можете повезати притиском на дугме „WPS“ на рутеру -settings = Подешавања мреже... -megabits-per-second = Mbps -gigabits-per-second = Gbps -terabits-per-second = Tbps diff --git a/cosmic-applet-network/i18n/th/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/th/cosmic_applet_network.ftl index 7d03ac66..e69de29b 100644 --- a/cosmic-applet-network/i18n/th/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/th/cosmic_applet_network.ftl @@ -1,4 +0,0 @@ -connect = เชื่อมต่อ -identity = ตัวตน -connected = เชื่อมต่อแล้ว -cancel = ยกเลิก diff --git a/cosmic-applet-network/i18n/uk/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/uk/cosmic_applet_network.ftl index cebc8087..687539ca 100644 --- a/cosmic-applet-network/i18n/uk/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/uk/cosmic_applet_network.ftl @@ -8,15 +8,15 @@ ipv6 = IPv6-адреса mac = MAC megabits-per-second = Мбіт/с connected = З'єднано -connecting = З’єднання -connect = З’єднати +connecting = Підключення +connect = З'єднати cancel = Скасувати settings = Налаштування мережі... visible-wireless-networks = Видимі бездротові мережі enter-password = Введіть пароль або ключ шифрування -router-wps-button = Також можна під’єднатися, натиснувши кнопку «WPS» на маршрутизаторі -unable-to-connect = Не вдалося під’єднатися до мережі -check-wifi-connection = Переконайтеся, що Wi-Fi під’єднано до Інтернету, а пароль — правильний +router-wps-button = Також можна підключитися, натиснувши кнопку «WPS» на маршрутизаторі +unable-to-connect = Не вдалося підключитися до мережі +check-wifi-connection = Переконайтеся, що Wi-Fi підключено до Інтернету, а пароль — правильний reset = Скинути identity = Ідентичність vpn-connections = VPN-з'єднання diff --git a/cosmic-applet-network/i18n/zh-TW/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/zh-TW/cosmic_applet_network.ftl index fb7946e6..23234d4d 100644 --- a/cosmic-applet-network/i18n/zh-TW/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/zh-TW/cosmic_applet_network.ftl @@ -8,7 +8,7 @@ ipv4 = IPv4 位址 ipv6 = IPv6 位址 mac = MAC megabits-per-second = Mbps -connected = 已連線 +connected = 已經連線 connecting = 連線中 connect = 連線 cancel = 取消 diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index b9baa109..727d9b10 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -1,21 +1,25 @@ -use indexmap::IndexMap; -use nmrs::{ - ActiveConnection, ActiveConnectionState, ConnectByUuidConfig, ConnectType, ConnectivityState, - EapOptions, NetworkEvent, NetworkManager as NmrsManager, NetworkSnapshot, WifiSecurity, - agent::{SecretAgent, SecretAgentCapabilities, SecretRequest, SecretResponder, SecretSetting}, +use anyhow::Context; +use cosmic_dbus_networkmanager::settings::{NetworkManagerSettings, connection::Settings}; +use cosmic_settings_network_manager_subscription::{ + self as network_manager, NetworkManagerState, UUID, + active_conns::active_conns_subscription, + available_wifi::{AccessPoint, NetworkType}, + current_networks::ActiveConnectionInfo, + hw_address::HwAddress, + nm_secret_agent::{self, PasswordFlag, SecretSender}, }; +use indexmap::IndexMap; use rustc_hash::FxHashSet; use secure_string::SecureString; use std::{ borrow::Cow, - collections::{BTreeMap, HashMap}, - fmt, - str::FromStr, + collections::{BTreeMap, BTreeSet}, sync::{Arc, LazyLock}, + time::Duration, }; use cosmic::{ - Element, Task, app, + Apply, Element, Task, app, applet::{ menu_button, menu_control_padding, padded_control, token::subscription::{TokenRequest, TokenUpdate, activation_token_subscription}, @@ -25,22 +29,23 @@ use cosmic::{ iced::core::window, iced::{ Alignment, Length, Subscription, - platform_specific::shell::wayland::commands::popup::destroy_popup, + platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup}, }, surface, theme, widget::{ - Id, button, column, container, divider, + Column, Id, Row, button, column, container, divider, icon::{self, from_name}, - indeterminate_circular, row, scrollable, secure_input, text, text_input, toggler, + row, scrollable, secure_input, text, text_input, toggler, }, }; - -use futures::{ - StreamExt, - channel::mpsc::{UnboundedReceiver, UnboundedSender, unbounded}, - lock::Mutex as AsyncMutex, +use cosmic_dbus_networkmanager::interface::{ + access_point, + enums::{ActiveConnectionState, DeviceState, NmConnectivityState, NmState}, }; +use futures::{StreamExt, channel::mpsc::TrySendError}; +use zbus::{Connection, zvariant::ObjectPath}; + use crate::{config, fl}; pub fn run() -> cosmic::iced::Result { @@ -60,6 +65,25 @@ enum NewConnectionState { Failure(AccessPoint), } +impl NewConnectionState { + pub fn ssid(&self) -> &str { + &match self { + Self::EnterPassword { access_point, .. } => access_point, + Self::Waiting(ap) => ap, + Self::Failure(ap) => ap, + } + .ssid + } + pub fn hw_address(&self) -> HwAddress { + match self { + Self::EnterPassword { access_point, .. } => access_point, + Self::Waiting(ap) => ap, + Self::Failure(ap) => ap, + } + .hw_address + } +} + impl From for AccessPoint { fn from(connection_state: NewConnectionState) -> Self { match connection_state { @@ -72,246 +96,56 @@ impl From for AccessPoint { pub static SECURE_INPUT_WIFI: LazyLock = LazyLock::new(Id::unique); -type Uuid = Arc; -type Ssid = Arc; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum NetworkType { - Open, - Password, - Eap, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum DeviceState { - Unknown, - Unmanaged, - Unavailable, - Disconnected, - NeedAuth, - Activated, - Failed, - Other, -} - -impl From<&nmrs::DeviceState> for DeviceState { - fn from(state: &nmrs::DeviceState) -> Self { - match state { - nmrs::DeviceState::Unmanaged => Self::Unmanaged, - nmrs::DeviceState::Unavailable => Self::Unavailable, - nmrs::DeviceState::Disconnected => Self::Disconnected, - nmrs::DeviceState::NeedAuth => Self::NeedAuth, - nmrs::DeviceState::Activated => Self::Activated, - nmrs::DeviceState::Failed => Self::Failed, - nmrs::DeviceState::Other(_) => Self::Unknown, - _ => Self::Other, - } - } -} - -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct HwAddress([u8; 6]); - -impl HwAddress { - fn as_string(self) -> String { - self.0 - .iter() - .map(|byte| format!("{byte:02X}")) - .collect::>() - .join(":") - } -} - -impl FromStr for HwAddress { - type Err = (); - - fn from_str(value: &str) -> Result { - let mut bytes = [0; 6]; - let mut parts = value.split(':'); - for byte in &mut bytes { - let Some(part) = parts.next() else { - return Err(()); - }; - *byte = u8::from_str_radix(part, 16).map_err(|_| ())?; - } - if parts.next().is_some() { - return Err(()); - } - Ok(Self(bytes)) - } -} - -impl fmt::Display for HwAddress { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.as_string()) - } -} - -fn same_access_point(left: &AccessPoint, right: &AccessPoint) -> bool { - left.ssid == right.ssid - && left.hw_address == right.hw_address - && left.interface == right.interface -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct AccessPoint { - pub ssid: Ssid, - pub network_type: NetworkType, - pub hw_address: HwAddress, - pub strength: u8, - pub state: DeviceState, - pub working: bool, - pub wps_push: bool, - pub interface: Option, -} - -#[derive(Debug, Clone)] -pub enum ActiveConnectionInfo { - Wired { - name: String, - hw_address: String, - speed: u32, - ip4_address: Option, - ip6_address: Option, - }, - WiFi { - name: String, - ip4_address: Option, - ip6_address: Option, - state: ActiveConnectionState, - strength: u8, - hw_address: String, - }, - Vpn { - name: String, - ip4_address: Option, - ip6_address: Option, - }, -} - -impl ActiveConnectionInfo { - fn name(&self) -> &str { - match self { - Self::Wired { name, .. } | Self::WiFi { name, .. } | Self::Vpn { name, .. } => name, - } - } -} - -#[derive(Debug, Clone)] -pub struct NetworkManagerState { - pub wifi_enabled: bool, - pub airplane_mode: bool, - pub connectivity: ConnectivityState, - pub active_conns: Vec, - pub known_access_points: Vec, - pub wireless_access_points: Vec, -} - -impl Default for NetworkManagerState { - fn default() -> Self { - Self { - wifi_enabled: true, - airplane_mode: false, - connectivity: ConnectivityState::Unknown, - active_conns: Vec::new(), - known_access_points: Vec::new(), - wireless_access_points: Vec::new(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum DeviceType { - Wifi, -} - -#[derive(Clone, Debug)] -pub struct DeviceConnection { - pub id: String, -} - -#[derive(Clone, Debug)] -pub struct DeviceInfo { - pub interface: String, - pub device_type: DeviceType, - pub active_connection: Option<(DeviceConnection,)>, - pub known_connections: Vec, -} - -#[derive(Debug, Clone)] -pub struct AppletSnapshot { - pub state: NetworkManagerState, - pub devices: Vec, - pub known_vpns: IndexMap, - pub ssid_to_uuid: BTreeMap, Box>, - pub captive_portal_url: Option, -} - #[derive(Default, Debug, Clone)] pub struct MyNetworkState { - pub known_vpns: IndexMap, + pub known_vpns: IndexMap, pub ssid_to_uuid: BTreeMap, Box>, - pub devices: Vec>, + pub devices: Vec>, + pub password: Option, + pub connecting: BTreeSet, pub nm_state: NetworkManagerState, pub requested_vpn: Option, - pub pending_vpn: Option, } -/// Shared, take-once handle to an `nmrs` [`SecretResponder`]. Cloned freely -/// across `Message` boundaries; the first consumer to `lock().take()` it owns -/// the reply to NetworkManager. -pub type SecretResponderHandle = Arc>>; - #[derive(Debug, Clone)] pub struct RequestedVpn { + name: String, uuid: Arc, description: Option, password: SecureString, password_hidden: bool, - responder: SecretResponderHandle, - /// VPN secret keys NM hinted as needed (e.g. `["password"]`). When empty, - /// `"password"` is used as a fallback. - secret_keys: Vec, -} - -#[derive(Debug, Clone)] -pub struct PendingVpn { - uuid: Arc, - action: PendingVpnAction, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum PendingVpnAction { - Activate, - Deactivate, + tx: SecretSender, } #[derive(Clone, Debug)] pub enum ConnectionSettings { - Vpn { id: String }, + Vpn(VpnConnectionSettings), Wireguard { id: String }, } -/// Local mirror of the secret-agent events the applet cares about. Sourced -/// from `nmrs::agent` instead of the previous `nm_secret_agent` subscription. -#[derive(Debug, Clone)] -pub enum NmAgentEvent { - RequestSecret { - connection_uuid: String, - connection_id: String, - setting: AgentSetting, - responder: SecretResponderHandle, - }, - CancelGetSecrets, - Failed(String), +#[derive(Clone, Debug, Default)] +pub struct VpnConnectionSettings { + id: String, + username: Option, + connection_type: Option, + password_flag: Option, } -#[derive(Debug, Clone)] -pub enum AgentSetting { - WifiPsk { ssid: String }, - WifiEap, - Vpn { secret_keys: Vec }, - Other, +#[derive(Clone, Debug, Eq, PartialEq)] +enum ConnectionType { + Password, +} + +impl VpnConnectionSettings { + fn password_flag(&self) -> Option { + self.connection_type + .as_ref() + .is_some_and(|ct| match ct { + ConnectionType::Password => true, + }) + .then_some(self.password_flag) + .flatten() + } } #[derive(Default)] @@ -321,19 +155,22 @@ struct CosmicNetworkApplet { popup: Option, // NM state + nm_sender: Option>, + nm_task: Option>, + secret_tx: Option>, nm_state: MyNetworkState, // UI state show_visible_networks: bool, show_available_vpns: bool, new_connection: Option, + conn: Option, toggle_wifi_ctr: u128, token_tx: Option>, - secret_agent_reregister_tx: Option>, failed_known_ssids: FxHashSet>, /// When defined, displays connections for the specific device. - active_device: Option>, + active_device: Option>, } fn wifi_icon(strength: u8) -> &'static str { @@ -427,19 +264,13 @@ fn vpn_section<'a>( if show_available_vpns { for (uuid, connection) in &nm_state.known_vpns { let id = match connection { - ConnectionSettings::Vpn { id } | ConnectionSettings::Wireguard { id } => { - id.as_str() - } + ConnectionSettings::Vpn(connection) => connection.id.as_str(), + ConnectionSettings::Wireguard { id } => id.as_str(), }; // Check if this VPN is currently active let is_active = nm_state.nm_state.active_conns.iter().any( |conn| matches!(conn, ActiveConnectionInfo::Vpn { name, .. } if name == id), ); - let pending_action = nm_state - .pending_vpn - .as_ref() - .filter(|pending| pending.uuid.as_ref() == uuid.as_ref()) - .map(|pending| pending.action); let mut btn_content = vec![ icon::from_name("network-vpn-symbolic") @@ -452,9 +283,6 @@ fn vpn_section<'a>( if is_active { btn_content.push(text::body(fl!("connected")).align_x(Alignment::End).into()); } - if pending_action.is_some() { - btn_content.push(indeterminate_circular().size(24.0).into()); - } let mut btn = menu_button( row::with_children(btn_content) @@ -462,9 +290,7 @@ fn vpn_section<'a>( .spacing(8), ); - btn = if pending_action.is_some() { - btn - } else if is_active { + btn = if is_active { btn.on_press(Message::DeactivateVpn(uuid.clone())) } else { btn.on_press(Message::ActivateVpn(uuid.clone())) @@ -478,341 +304,7 @@ fn vpn_section<'a>( vpn_col } -fn ip_address_elements<'a>( - ip4_address: &Option, - _ip6_address: &Option, -) -> Vec> { - let mut elements = Vec::with_capacity(1); - if let Some(addr) = ip4_address { - // Strip the subnet mask (e.g. "10.0.0.2/24" -> "10.0.0.2"); the drop-down - // only needs the address itself for glancing at the host on a local network. - let addr = addr.split('/').next().unwrap_or(addr.as_str()); - elements.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into()); - } - elements -} - -fn network_type(security: nmrs::SecurityFeatures) -> NetworkType { - match security.preferred_connect_type() { - ConnectType::Open | ConnectType::Owe => NetworkType::Open, - ConnectType::Eap => NetworkType::Eap, - ConnectType::Psk | ConnectType::Sae => NetworkType::Password, - _ => NetworkType::Password, - } -} - -fn wifi_security( - access_point: &AccessPoint, - identity: Option, - password: Option, -) -> WifiSecurity { - match access_point.network_type { - NetworkType::Open => WifiSecurity::Open, - NetworkType::Eap => WifiSecurity::WpaEap { - opts: EapOptions::new( - identity.unwrap_or_default(), - password - .as_ref() - .map(|password| password.unsecure().to_owned()) - .unwrap_or_default(), - ), - }, - NetworkType::Password => WifiSecurity::WpaPsk { - psk: password - .as_ref() - .map(|password| password.unsecure().to_owned()) - .unwrap_or_default(), - }, - } -} - -fn connect_access_point_task( - access_point: AccessPoint, - identity: Option, - password: Option, -) -> Task> { - cosmic::task::future(async move { - let ssid = access_point.ssid.to_string(); - let interface = access_point.interface.clone(); - let bssid = access_point.hw_address.as_string(); - let security = wifi_security(&access_point, identity, password); - match NmrsManager::new().await { - Ok(nm) => { - match nm - .connect_to_bssid(&ssid, Some(&bssid), interface.as_deref(), security) - .await - { - Ok(()) => Message::ConnectionAttemptFinished { - access_point, - success: true, - error: None, - }, - Err(e) => Message::ConnectionAttemptFinished { - access_point, - success: false, - error: Some(e.to_string()), - }, - } - } - Err(e) => Message::Error(format!("nmrs init: {e}")), - } - }) - .map(cosmic::Action::App) -} - -fn snapshot_task() -> Task { - cosmic::task::future(async move { - let nm = match NmrsManager::new().await { - Ok(nm) => nm, - Err(e) => return Message::Error(format!("nmrs init: {e}")), - }; - - match nm.snapshot().await { - Ok(snapshot) => Message::Snapshot(snapshot_to_applet(snapshot)), - Err(e) => Message::Error(format!("snapshot: {e}")), - } - }) -} - -fn network_events_task() -> Task { - cosmic::Task::stream(async_fn_stream::fn_stream(|emitter| async move { - let nm = match NmrsManager::new().await { - Ok(nm) => nm, - Err(e) => { - let _ = emitter - .emit(Message::Error(format!("nmrs init: {e}"))) - .await; - return; - } - }; - let mut events = match nm.network_events().await { - Ok(events) => events, - Err(e) => { - let _ = emitter - .emit(Message::Error(format!("network events: {e}"))) - .await; - return; - } - }; - - while let Some(event) = events.next().await { - match event { - Ok(event) => { - let _ = emitter.emit(Message::NetworkEvent(event)).await; - } - Err(e) => { - let _ = emitter - .emit(Message::Error(format!("network event: {e}"))) - .await; - } - } - } - })) -} - -fn snapshot_to_applet(snapshot: NetworkSnapshot) -> AppletSnapshot { - let summary = snapshot.applet_summary(); - let mut known_vpns = IndexMap::new(); - for vpn in summary.saved_vpns.values() { - let uuid: Uuid = Arc::from(vpn.uuid.as_str()); - let entry = match vpn.kind { - Some(nmrs::VpnKind::WireGuard) => ConnectionSettings::Wireguard { id: vpn.id.clone() }, - _ => ConnectionSettings::Vpn { id: vpn.id.clone() }, - }; - known_vpns.insert(uuid, entry); - } - - let mut ssid_to_uuid = BTreeMap::new(); - for (ssid, profiles) in &summary.known_wifi { - if let Some(profile) = profiles.first() { - ssid_to_uuid.insert( - ssid.clone().into_boxed_str(), - profile.uuid.clone().into_boxed_str(), - ); - } - } - - let active_conns = snapshot - .active_connections - .iter() - .filter_map(|conn| match conn { - ActiveConnection::Wired(wired) => Some(ActiveConnectionInfo::Wired { - name: wired.id.clone(), - hw_address: wired.hw_address.clone().unwrap_or_default(), - speed: wired.speed_mbps.unwrap_or_default(), - ip4_address: wired.ip4_address.clone(), - ip6_address: wired.ip6_address.clone(), - }), - ActiveConnection::Wifi(wifi) - if known_vpns.values().any(|connection| { - matches!( - connection, - ConnectionSettings::Vpn { id } | ConnectionSettings::Wireguard { id } - if id == &wifi.ssid - ) - }) => - { - Some(ActiveConnectionInfo::Vpn { - name: wifi.ssid.clone(), - ip4_address: wifi.ip4_address.clone(), - ip6_address: wifi.ip6_address.clone(), - }) - } - ActiveConnection::Wifi(wifi) => Some(ActiveConnectionInfo::WiFi { - name: wifi.ssid.clone(), - ip4_address: wifi.ip4_address.clone(), - ip6_address: wifi.ip6_address.clone(), - state: wifi.state, - strength: wifi.strength.unwrap_or_default(), - hw_address: wifi.bssid.clone().unwrap_or_default(), - }), - ActiveConnection::Vpn(vpn) => Some(ActiveConnectionInfo::Vpn { - name: vpn.id.clone(), - ip4_address: vpn.ip4_address.clone(), - ip6_address: vpn.ip6_address.clone(), - }), - ActiveConnection::Other(_) | _ => None, - }) - .collect(); - - let mut wireless_access_points = summary - .wifi_groups - .iter() - .filter(|group| !group.ssid.is_empty() && !group.strongest.ssid_bytes.is_empty()) - .map(|group| { - let strongest = &group.strongest; - AccessPoint { - ssid: Arc::from(group.ssid.as_str()), - network_type: network_type(strongest.security), - hw_address: HwAddress::from_str(&strongest.bssid).unwrap_or_default(), - strength: strongest.strength, - state: DeviceState::from(&strongest.device_state), - working: false, - wps_push: strongest.security.wps, - interface: Some(group.interface.clone()), - } - }) - .collect::>(); - wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength)); - - let known_access_points = summary - .wifi_groups - .iter() - .filter(|group| group.known || group.active) - .map(|group| { - let strongest = &group.strongest; - let device_state = DeviceState::from(&strongest.device_state); - AccessPoint { - ssid: Arc::from(group.ssid.as_str()), - network_type: network_type(strongest.security), - hw_address: HwAddress::from_str(&strongest.bssid).unwrap_or_default(), - strength: strongest.strength, - state: if group.active { - DeviceState::Activated - } else if matches!(device_state, DeviceState::Activated) { - DeviceState::Disconnected - } else { - device_state - }, - working: false, - wps_push: strongest.security.wps, - interface: Some(group.interface.clone()), - } - }) - .collect::>(); - - let devices = snapshot - .wifi_devices - .iter() - .map(|device| { - let known_connections = summary - .known_wifi - .iter() - .filter(|(ssid, _)| { - summary - .wifi_groups - .iter() - .any(|group| group.interface == device.interface && group.ssid == **ssid) - }) - .map(|(ssid, _)| DeviceConnection { id: ssid.clone() }) - .collect(); - DeviceInfo { - interface: device.interface.clone(), - device_type: DeviceType::Wifi, - active_connection: device - .active_ssid - .as_ref() - .map(|ssid| (DeviceConnection { id: ssid.clone() },)), - known_connections, - } - }) - .collect(); - - AppletSnapshot { - state: NetworkManagerState { - wifi_enabled: snapshot.wifi.enabled, - airplane_mode: summary.airplane_mode.is_airplane_mode(), - connectivity: summary.connectivity.state, - active_conns, - known_access_points, - wireless_access_points, - }, - devices, - known_vpns, - ssid_to_uuid, - captive_portal_url: summary.connectivity.captive_portal_url.clone(), - } -} - impl CosmicNetworkApplet { - fn apply_snapshot(&mut self, snapshot: AppletSnapshot) { - let previous_connectivity = self.nm_state.nm_state.connectivity; - self.nm_state.devices = snapshot.devices.into_iter().map(Arc::new).collect(); - self.nm_state.known_vpns = snapshot.known_vpns; - self.nm_state.ssid_to_uuid = snapshot.ssid_to_uuid; - self.update_nm_state(snapshot.state); - self.clear_completed_pending_vpn(); - - if !previous_connectivity.is_captive() && self.nm_state.nm_state.connectivity.is_captive() { - let mut browser = std::process::Command::new("xdg-open"); - browser.arg( - snapshot - .captive_portal_url - .as_deref() - .unwrap_or("http://204.pop-os.org/"), - ); - tokio::spawn(cosmic::process::spawn(browser)); - } - } - - fn clear_completed_pending_vpn(&mut self) { - let Some(pending) = self.nm_state.pending_vpn.as_ref() else { - return; - }; - let Some(connection) = self.nm_state.known_vpns.get(&pending.uuid) else { - self.nm_state.pending_vpn = None; - self.update_icon_name(); - return; - }; - let id = match connection { - ConnectionSettings::Vpn { id } | ConnectionSettings::Wireguard { id } => id, - }; - let is_active = self - .nm_state - .nm_state - .active_conns - .iter() - .any(|conn| matches!(conn, ActiveConnectionInfo::Vpn { name, .. } if name == id)); - let completed = match pending.action { - PendingVpnAction::Activate => is_active, - PendingVpnAction::Deactivate => !is_active, - }; - if completed { - self.nm_state.pending_vpn = None; - self.update_icon_name(); - } - } - fn update_nm_state(&mut self, mut new_state: NetworkManagerState) { self.update_togglers(&new_state); // check for failed conns that can be reset @@ -822,7 +314,7 @@ impl CosmicNetworkApplet { }; if matches!(state, ActiveConnectionState::Activated) { - self.failed_known_ssids.remove(new_s.name()); + self.failed_known_ssids.remove(new_s.name().as_str()); continue; } if matches!( @@ -849,22 +341,6 @@ impl CosmicNetworkApplet { } fn update_icon_name(&mut self) { - if self - .nm_state - .pending_vpn - .as_ref() - .is_some_and(|pending| pending.action == PendingVpnAction::Activate) - || self - .nm_state - .nm_state - .active_conns - .iter() - .any(|conn| matches!(conn, ActiveConnectionInfo::Vpn { .. })) - { - self.icon_name = "network-vpn-symbolic".to_string(); - return; - } - self.icon_name = self .nm_state .nm_state @@ -877,7 +353,12 @@ impl CosmicNetworkApplet { "network-wired-disconnected-symbolic", ActiveConnectionInfo::WiFi { strength, .. }, ) => wifi_icon(*strength), - (_, ActiveConnectionInfo::Wired { .. }) => "network-wired-symbolic", + (_, ActiveConnectionInfo::Wired { .. }) + if icon_name != "network-vpn-symbolic" => + { + "network-wired-symbolic" + } + (_, ActiveConnectionInfo::Vpn { .. }) => "network-vpn-symbolic", _ => icon_name, }, ) @@ -885,12 +366,15 @@ impl CosmicNetworkApplet { } fn update_togglers(&mut self, state: &NetworkManagerState) { + let mut changed = false; if self.nm_state.nm_state.wifi_enabled != state.wifi_enabled { self.nm_state.nm_state.wifi_enabled = state.wifi_enabled; + changed = true; } if self.nm_state.nm_state.airplane_mode != state.airplane_mode { self.nm_state.nm_state.airplane_mode = state.airplane_mode; + changed = true; } } @@ -913,106 +397,55 @@ impl CosmicNetworkApplet { } fn connect_vpn(&mut self, uuid: Arc) -> Task> { - cosmic::task::future(async move { - let error = match NmrsManager::new().await { - Ok(nm) => nm - .connect_by_uuid(&uuid, ConnectByUuidConfig::default()) - .await - .err() - .map(|e| format!("activate VPN {uuid}: {e}")), - Err(e) => Some(format!("nmrs init: {e}")), - }; - Message::VpnOperationFinished { - uuid, - action: PendingVpnAction::Activate, - error, - } - }) - .map(cosmic::Action::App) + if let Some((tx, conn)) = self.nm_sender.clone().zip(self.conn.clone()) { + cosmic::task::future(async move { + // Find the connection by UUID + if let Ok(nm_settings) = NetworkManagerSettings::new(&conn).await { + if let Ok(connections) = nm_settings.list_connections().await { + for connection in connections { + if let Ok(settings) = connection.get_settings().await { + let settings = Settings::new(settings); + if let Some(conn_settings) = &settings.connection { + if conn_settings.uuid.as_ref().is_some_and(|conn_uuid| { + conn_uuid.as_str() == uuid.as_ref() + }) { + let path = connection.inner().path().clone().to_owned(); + if let Err(err) = + tx.unbounded_send(network_manager::Request::Activate( + ObjectPath::try_from("/").unwrap(), + path, + )) + { + if err.is_disconnected() { + return zbus::Connection::system() + .await + .context( + "failed to create system dbus connection", + ) + .map_or_else( + |why| Message::Error(why.to_string()), + Message::NetworkManagerConnect, + ); + } + + tracing::error!("{err:?}"); + } + break; + } + } + } + } + } + } + Message::Refresh + }) + } else { + tracing::warn!("No sender available to activate VPN."); + Task::none() + } } } -/// Registers an `nmrs` secret agent on the system bus and yields its -/// requests + cancellations as [`NmAgentEvent`] for the applet to handle. -fn secret_agent_task( - identifier: String, - mut reregister_requests: UnboundedReceiver<()>, -) -> Task { - cosmic::Task::stream(async_fn_stream::fn_stream(move |emitter| async move { - let registration = SecretAgent::builder() - .with_identifier(identifier) - .with_object_path("/org/freedesktop/NetworkManager/SecretAgent") - .with_capabilities(SecretAgentCapabilities::VPN_HINTS) - .register() - .await; - - let (mut handle, mut requests) = match registration { - Ok(pair) => pair, - Err(e) => { - let _ = emitter.emit(NmAgentEvent::Failed(e.to_string())).await; - return; - } - }; - - loop { - tokio::select! { - req = requests.next() => match req { - Some(req) => { - let event = secret_request_to_event(req); - let _ = emitter.emit(event).await; - } - None => break, - }, - cancel = handle.cancellations().next() => match cancel { - Some(_reason) => { - let _ = emitter.emit(NmAgentEvent::CancelGetSecrets).await; - } - None => break, - }, - Some(()) = reregister_requests.next() => { - if let Err(e) = handle.reregister().await { - tracing::warn!("failed to re-register secret agent: {e}"); - } - }, - } - } - - if let Err(e) = handle.unregister().await { - tracing::warn!("failed to unregister secret agent: {e}"); - } - })) -} - -fn secret_request_to_event(req: SecretRequest) -> NmAgentEvent { - let setting = match req.setting { - SecretSetting::WifiPsk { ssid } => AgentSetting::WifiPsk { ssid }, - SecretSetting::WifiEap { .. } => AgentSetting::WifiEap, - SecretSetting::Vpn { .. } => AgentSetting::Vpn { - secret_keys: req.hints.clone(), - }, - _ => AgentSetting::Other, - }; - - NmAgentEvent::RequestSecret { - connection_uuid: req.connection_uuid, - connection_id: req.connection_id, - setting, - responder: Arc::new(AsyncMutex::new(Some(req.responder))), - } -} - -/// Reply with [`NoSecrets`](nmrs::agent::SecretResponder::no_secrets) to free -/// NetworkManager when the applet decides not to use the responder. Dropping -/// it would also auto-reply, but doing it explicitly keeps the log clean. -fn release_responder(responder: SecretResponderHandle) -> Task> { - cosmic::task::future(async move { - if let Some(r) = responder.lock().await.take() { - let _ = r.no_secrets().await; - } - Message::NoOp - }) -} - #[derive(Debug, Clone)] pub(crate) enum Message { TogglePopup, @@ -1027,39 +460,35 @@ pub(crate) enum Message { TogglePasswordVisibility, FocusSecureInput, NoOp, - #[allow(dead_code)] // required by `cosmic::applet` surface path; not always emitted - Surface(surface::Action), + Surface(surface::Action), ActivateVpn(Arc), // UUID of VPN to activate DeactivateVpn(Arc), // UUID of VPN to deactivate - VpnOperationFinished { - uuid: Arc, - action: PendingVpnAction, - error: Option, - }, - ToggleVpnList, // Show/hide available VPNs + ToggleVpnList, // Show/hide available VPNs /// An update from the secret agent - SecretAgent(NmAgentEvent), + SecretAgent(network_manager::nm_secret_agent::Event), /// Connect to a WiFi network access point. - Connect(Ssid, HwAddress), + Connect(network_manager::SSID, HwAddress), /// Connect with a password ConnectWithPassword, + KnownConnections(IndexMap), + /// Settings for known connections. + ConnectionSettings(BTreeMap, Box>), /// Disconnect from an access point. - Disconnect(Ssid, HwAddress), - ConnectionAttemptFinished { - access_point: AccessPoint, - success: bool, - error: Option, - }, + Disconnect(network_manager::SSID, HwAddress), /// An error occurred. Error(String), /// Identity update from the dialog IdentityUpdate(String), - /// An update from NetworkManager. - NetworkEvent(NetworkEvent), + /// An update from the network manager daemon + NetworkManager(network_manager::Event), + /// Successfully connected to the system dbus. + NetworkManagerConnect(zbus::Connection), /// Update the password from the dialog PasswordUpdate(SecureString), - /// Update applet state from NetworkManager. - Snapshot(AppletSnapshot), + /// Update NetworkManagerState + UpdateState(NetworkManagerState), + /// Update the devices lists + UpdateDevices(Vec), /// Toggle WiFi access WiFiEnable(bool), /// Refresh state @@ -1069,7 +498,258 @@ pub(crate) enum Message { VPNPasswordUpdate(SecureString), CancelVPNConnection, /// Selects a device to display connections from - SelectDevice(Option>), + SelectDevice(Option>), +} + +#[derive(Debug, Clone)] +struct Password { + ssid: network_manager::SSID, + hw_address: HwAddress, + identity: Option, + password: SecureString, + password_hidden: bool, + tx: SecretSender, +} + +fn connection_settings(conn: zbus::Connection) -> Task { + let settings = async move { + let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?; + + _ = settings.load_connections(&[]).await; + + let settings = settings + // Get a list of known connections. + .list_connections() + .await? + // Prepare for wrapping in a concurrent stream. + .into_iter() + .map(|conn| async move { conn }) + // Create a concurrent stream for each connection. + .apply(futures::stream::FuturesOrdered::from_iter) + // Concurrently fetch settings for each connection. + .filter_map(|conn| async move { + conn.get_settings() + .await + .map(network_manager::Settings::new) + .ok() + }) + // Reduce the settings list into a SSID->UUID map. + .fold(BTreeMap::new(), |mut set, settings| async move { + if let Some(ref wifi) = settings.wifi + && let Some(ssid) = wifi + .ssid + .clone() + .and_then(|ssid| String::from_utf8(ssid).ok()) + && let Some(ref connection) = settings.connection + && let Some(uuid) = connection.uuid.clone() + { + set.insert(ssid.into(), uuid.into()); + return set; + } + + set + }) + .await; + + Ok::<_, zbus::Error>(settings) + }; + + cosmic::task::future(async move { + settings + .await + .context("failed to get connection settings") + .map_or_else( + |why| Message::Error(why.to_string()), + Message::ConnectionSettings, + ) + }) +} + +pub fn update_state(conn: zbus::Connection) -> Task { + cosmic::task::future(async move { + match NetworkManagerState::new(&conn).await { + Ok(state) => Message::UpdateState(state), + Err(why) => Message::Error(why.to_string()), + } + }) +} + +pub fn update_devices(conn: zbus::Connection) -> Task { + cosmic::task::future(async move { + let filter = + |device_type| matches!(device_type, network_manager::devices::DeviceType::Wifi); + match network_manager::devices::list(&conn, filter).await { + Ok(devices) => Message::UpdateDevices(devices), + Err(why) => Message::Error(why.to_string()), + } + }) +} + +impl CosmicNetworkApplet { + fn connect(&mut self, conn: zbus::Connection) -> Task { + if self.nm_task.is_none() { + let popup = self.popup; + let (canceller, task) = crate::utils::forward_event_loop(move |emitter| async move { + let (tx, mut rx) = futures::channel::mpsc::channel(1); + + if popup.is_some() { + let watchers = std::pin::pin!(async move { + futures::join!( + network_manager::watch(conn.clone(), tx.clone()), + network_manager::active_conns::watch(conn.clone(), tx.clone(),), + network_manager::wireless_enabled::watch(conn.clone(), tx.clone()), + network_manager::watch_connections_changed(conn, tx,) + ); + }); + let forwarder = std::pin::pin!(async move { + while let Some(message) = rx.next().await { + _ = emitter.emit(Message::NetworkManager(message)).await; + } + }); + + futures::future::select(watchers, forwarder).await; + } else { + let watchers = std::pin::pin!(async move { + futures::join!( + network_manager::watch(conn.clone(), tx.clone()), + network_manager::active_conns::watch(conn.clone(), tx.clone(),), + network_manager::wireless_enabled::watch(conn.clone(), tx.clone()), + ); + }); + let forwarder = std::pin::pin!(async move { + while let Some(message) = rx.next().await { + _ = emitter.emit(Message::NetworkManager(message)).await; + } + }); + + futures::future::select(watchers, forwarder).await; + }; + }); + + self.nm_task = Some(canceller); + return task.map(Message::from); + } + + Task::none() + } +} + +fn load_vpns(conn: zbus::Connection) -> Task { + let settings = async move { + let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?; + + _ = settings.load_connections(&[]).await; + + let settings = settings + // Get a list of known connections. + .list_connections() + .await? + // Prepare for wrapping in a concurrent stream. + .into_iter() + .map(|conn| async move { conn }) + // Create a concurrent stream for each connection. + .apply(futures::stream::FuturesOrdered::from_iter) + // Concurrently fetch settings for each connection, and filter for VPN. + .filter_map(|conn| async move { + let settings = conn.get_settings().await.ok()?; + + let connection = settings.get("connection")?; + + match connection + .get("type")? + .downcast_ref::() + .ok()? + .as_str() + { + "vpn" => (), + + "wireguard" => { + let id = connection.get("id")?.downcast_ref::().ok()?; + let uuid = connection.get("uuid")?.downcast_ref::().ok()?; + return Some((Arc::from(uuid), ConnectionSettings::Wireguard { id })); + } + + _ => return None, + } + + let vpn = settings.get("vpn")?; + let id = connection.get("id")?.downcast_ref::().ok()?; + let uuid = connection.get("uuid")?.downcast_ref::().ok()?; + + let (connection_type, username, password_flag) = vpn + .get("data") + .and_then(|data| data.downcast_ref::().ok()) + .map(|dict| { + let (mut connection_type, mut password_flag) = (None, None); + let mut username = vpn + .get("user-name") + .and_then(|u| u.downcast_ref::().ok()); + if dict + .get::(&String::from("connection-type")) + .ok() + .flatten() + .as_deref() + // may be "password" or "password-tls" + .is_some_and(|p| p.starts_with("password")) + { + connection_type = Some(ConnectionType::Password); + username = Some(username.unwrap_or_default()); + + password_flag = dict + .get::(&String::from("password-flags")) + .ok() + .flatten() + .and_then(|value| match value.as_str() { + "0" => Some(PasswordFlag::None), + "1" => Some(PasswordFlag::AgentOwned), + "2" => Some(PasswordFlag::NotSaved), + "4" => Some(PasswordFlag::NotRequired), + _ => None, + }); + } + + (connection_type, username, password_flag) + }) + .unwrap_or_default(); + + Some(( + Arc::from(uuid), + ConnectionSettings::Vpn(VpnConnectionSettings { + id, + connection_type, + password_flag, + username, + }), + )) + }) + // Reduce the settings list into + .fold(IndexMap::new(), |mut set, (uuid, data)| async move { + set.insert(uuid, data); + set + }) + .await; + + Ok::<_, zbus::Error>(settings) + }; + + cosmic::task::future(async move { + settings.await.map_or_else( + |why| Message::Error(why.to_string()), + Message::KnownConnections, + ) + }) +} + +fn system_conn() -> Task { + cosmic::Task::future(async move { + zbus::Connection::system() + .await + .context("failed to create system dbus connection") + .map_or_else( + |why| Message::Error(why.to_string()), + Message::NetworkManagerConnect, + ) + }) } impl cosmic::Application for CosmicNetworkApplet { @@ -1079,30 +759,14 @@ impl cosmic::Application for CosmicNetworkApplet { const APP_ID: &'static str = config::APP_ID; fn init(core: cosmic::app::Core, _flags: ()) -> (Self, app::Task) { - let applet = Self { + let mut applet = Self { core, icon_name: "network-wired-disconnected-symbolic".to_string(), token_tx: None, ..Default::default() }; - let uuid = uuid::Uuid::new_v4().to_string().replace("-", "_"); - let my_id = - format!("com.system76.CosmicSettings.Applet._{uuid}.NetworkManager.SecretAgent",); - let (secret_agent_reregister_tx, secret_agent_reregister_rx) = unbounded(); - - ( - Self { - secret_agent_reregister_tx: Some(secret_agent_reregister_tx), - ..applet - }, - Task::batch(vec![ - snapshot_task(), - network_events_task(), - secret_agent_task(my_id, secret_agent_reregister_rx).map(Message::SecretAgent), - ]) - .map(cosmic::Action::App), - ) + (applet, system_conn().map(cosmic::Action::App)) } fn core(&self) -> &cosmic::app::Core { @@ -1121,62 +785,98 @@ impl cosmic::Application for CosmicNetworkApplet { return destroy_popup(p); } else { let mut tasks = Vec::with_capacity(2); - tasks.push(snapshot_task().map(cosmic::Action::App)); - tasks.push(cosmic::surface::surface_task( - cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); + if let Some(conn) = self.conn.clone() { + tasks.push(update_state(conn.clone())); + tasks.push(update_devices(conn.clone())); + tasks.push(load_vpns(conn)); + let (tx, rx) = tokio::sync::mpsc::channel(4); + self.secret_tx = Some(tx); + let my_id = format!( + "com.system76.CosmicSettings.Applet.{}.NetworkManager.SecretAgent", + uuid::Uuid::new_v4() + ); + tasks.push( + cosmic::Task::stream(nm_secret_agent::secret_agent_stream( + my_id.clone(), + rx, + )) + .map(Message::SecretAgent), + ); + } + // TODO request update of state maybe + let new_id = window::Id::unique(); + self.popup.replace(new_id); - let popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - popup_settings - }, - None, - ), - )); + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + None, + None, + None, + ); - return Task::batch(tasks); + tasks.push(system_conn()); + tasks.push(get_popup(popup_settings)); + + return Task::batch(tasks).map(cosmic::Action::App); } } Message::ToggleAirplaneMode(enabled) => { self.toggle_wifi_ctr += 1; - self.nm_state.nm_state.airplane_mode = enabled; - return cosmic::task::future(async move { - match NmrsManager::new().await { - Ok(nm) => match nm.set_airplane_mode(enabled).await { - Ok(()) => Message::Refresh, - Err(e) => { - tracing::warn!("set_airplane_mode partial failure: {e}"); - Message::Refresh - } - }, - Err(e) => Message::Error(format!("nmrs init: {e}")), + if let Some(tx) = self.nm_sender.as_mut() { + if let Err(err) = + tx.unbounded_send(network_manager::Request::SetAirplaneMode(enabled)) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); } - }) - .map(cosmic::Action::App); + } } Message::SelectWirelessAccessPoint(access_point) => { + let Some(tx) = self.nm_sender.as_ref() else { + return Task::none(); + }; + if matches!(access_point.network_type, NetworkType::Open) { - self.new_connection = Some(NewConnectionState::Waiting(access_point.clone())); - return connect_access_point_task(access_point, None, None); + if let Err(err) = + tx.unbounded_send(network_manager::Request::SelectAccessPoint( + access_point.ssid.clone(), + access_point.network_type, + self.secret_tx.clone(), + self.active_device.as_ref().map(|d| d.interface.clone()), + )) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); + } + self.new_connection = Some(NewConnectionState::Waiting(access_point)); } else { - let known = self + if self .nm_state .nm_state .known_access_points - .iter() - .any(|known| same_access_point(known, &access_point)); - if known { - self.new_connection = - Some(NewConnectionState::Waiting(access_point.clone())); - return connect_access_point_task(access_point, None, None); + .contains(&access_point) + { + if let Err(err) = + tx.unbounded_send(network_manager::Request::SelectAccessPoint( + access_point.ssid.clone(), + access_point.network_type, + self.secret_tx.clone(), + self.active_device.as_ref().map(|d| d.interface.clone()), + )) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); + } } self.new_connection = Some(NewConnectionState::EnterPassword { access_point, @@ -1211,6 +911,12 @@ impl cosmic::Application for CosmicNetworkApplet { Message::CloseRequested(id) => { if Some(id) == self.popup { self.popup = None; + if let Some(cancel) = self.nm_task.take() { + _ = cancel.send(()); + } + + self.secret_tx = None; + return system_conn().map(cosmic::Action::App); } } Message::OpenSettings => { @@ -1275,97 +981,79 @@ impl cosmic::Application for CosmicNetworkApplet { tracing::warn!("Failed to find known access point with ssid: {}", ssid); return Task::none(); }; - self.show_visible_networks = true; - let ssid_for_task = ssid.clone(); - let forget_task = cosmic::task::future(async move { - match NmrsManager::new().await { - Ok(nm) => match nm.forget(&ssid_for_task).await { - Ok(()) => Message::Refresh, - Err(e) => { - tracing::warn!("forget {ssid_for_task} failed: {e}"); - Message::Refresh - } - }, - Err(e) => Message::Error(format!("nmrs init: {e}")), + if let Some(tx) = self.nm_sender.as_ref() { + if let Err(err) = + tx.unbounded_send(network_manager::Request::Forget(ssid.into())) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); } - }) - .map(cosmic::Action::App); - let reconnect_task = connect_access_point_task(ap, None, None); - return Task::batch(vec![forget_task, reconnect_task]); + self.show_visible_networks = true; + return self.update(Message::SelectWirelessAccessPoint(ap)); + } } Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } Message::ActivateVpn(uuid) => { - self.nm_state.pending_vpn = Some(PendingVpn { - uuid: uuid.clone(), - action: PendingVpnAction::Activate, - }); - self.update_icon_name(); - return Task::batch(vec![ - snapshot_task().map(cosmic::Action::App), - self.connect_vpn(uuid.clone()), - ]); + return self.connect_vpn(uuid.clone()); } - Message::DeactivateVpn(uuid) => { - self.nm_state.pending_vpn = Some(PendingVpn { - uuid: uuid.clone(), - action: PendingVpnAction::Deactivate, - }); - self.update_icon_name(); - let disconnect_task = cosmic::task::future(async move { - let error = match NmrsManager::new().await { - Ok(nm) => nm - .disconnect_by_uuid(&uuid) - .await - .err() - .map(|e| format!("disconnect VPN {uuid}: {e}")), - Err(e) => Some(format!("nmrs init: {e}")), - }; - Message::VpnOperationFinished { - uuid, - action: PendingVpnAction::Deactivate, - error, + Message::DeactivateVpn(name) => { + if let Some(tx) = self.nm_sender.as_ref() { + if let Err(err) = tx.unbounded_send(network_manager::Request::Deactivate(name)) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); } - }) - .map(cosmic::Action::App); - return Task::batch(vec![ - snapshot_task().map(cosmic::Action::App), - disconnect_task, - ]); - } - Message::VpnOperationFinished { - uuid, - action, - error, - } => { - if self.nm_state.pending_vpn.as_ref().is_some_and(|pending| { - pending.uuid.as_ref() == uuid.as_ref() && pending.action == action - }) { - self.nm_state.pending_vpn = None; - self.update_icon_name(); } - if let Some(error) = error { - tracing::error!("{error}"); - } - return snapshot_task().map(cosmic::Action::App); } Message::ToggleVpnList => { self.show_available_vpns = !self.show_available_vpns; } Message::Connect(ssid, hw_address) => { - if let Some(ap) = self - .nm_state - .nm_state - .known_access_points - .iter_mut() - .find(|c| c.ssid == ssid && c.hw_address == hw_address) - { - ap.working = true; - return connect_access_point_task(ap.clone(), None, None); + let mut network_type = NetworkType::Open; + let tx = if let Some(tx) = self.nm_sender.as_ref() { + if let Some(ap) = self + .nm_state + .nm_state + .known_access_points + .iter_mut() + .find(|c| c.ssid == ssid && c.hw_address == hw_address) + { + network_type = ap.network_type; + ap.working = true; + } + tx + } else { + return Task::none(); + }; + if let Err(err) = tx.unbounded_send(network_manager::Request::SelectAccessPoint( + ssid, + network_type, + self.secret_tx.clone(), + self.active_device.as_ref().map(|d| d.interface.clone()), + )) { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); } } Message::ConnectWithPassword => { + // save password + let Some(tx) = self.nm_sender.as_ref() else { + return Task::none(); + }; + if let Some(NewConnectionState::EnterPassword { password, access_point, @@ -1373,44 +1061,55 @@ impl cosmic::Application for CosmicNetworkApplet { .. }) = self.new_connection.take() { + let is_enterprise: bool = matches!(access_point.network_type, NetworkType::EAP); + + if let Err(err) = tx.unbounded_send(network_manager::Request::Authenticate { + ssid: access_point.ssid.to_string(), + identity: is_enterprise.then(|| identity.clone()), + password, + secret_tx: self.secret_tx.clone(), + interface: self.active_device.as_ref().map(|d| d.interface.clone()), + }) { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + tracing::error!("Failed to authenticate with network manager"); + } self.new_connection - .replace(NewConnectionState::Waiting(access_point.clone())); - return connect_access_point_task(access_point, Some(identity), Some(password)); + .replace(NewConnectionState::Waiting(access_point)); } } + Message::ConnectionSettings(btree_map) => { + self.nm_state.ssid_to_uuid = btree_map; + } Message::Disconnect(ssid, hw_address) => { self.new_connection = None; - let interface = self - .nm_state - .nm_state - .known_access_points - .iter() - .find(|ap| ap.ssid == ssid && ap.hw_address == hw_address) - .and_then(|ap| ap.interface.clone()); - if let Some(ActiveConnectionInfo::WiFi { state, .. }) = - self.nm_state.nm_state.active_conns.iter_mut().find(|c| { - let c_hw_address = match c { - ActiveConnectionInfo::Wired { hw_address, .. } - | ActiveConnectionInfo::WiFi { hw_address, .. } => { - HwAddress::from_str(hw_address).unwrap_or_default() - } - ActiveConnectionInfo::Vpn { .. } => HwAddress::default(), - }; - c.name() == ssid.as_ref() && c_hw_address == hw_address - }) - { - *state = ActiveConnectionState::Deactivating; - } - return cosmic::task::future(async move { - match NmrsManager::new().await { - Ok(nm) => match nm.disconnect(interface.as_deref()).await { - Ok(()) => Message::Refresh, - Err(e) => Message::Error(format!("disconnect {ssid}: {e}")), - }, - Err(e) => Message::Error(format!("nmrs init: {e}")), + let tx = if let Some(tx) = self.nm_sender.as_ref() { + if let Some(ActiveConnectionInfo::WiFi { state, .. }) = + self.nm_state.nm_state.active_conns.iter_mut().find(|c| { + let c_hw_address = match c { + ActiveConnectionInfo::Wired { hw_address, .. } + | ActiveConnectionInfo::WiFi { hw_address, .. } => { + HwAddress::from_str(hw_address).unwrap() + } + ActiveConnectionInfo::Vpn { .. } => HwAddress::default(), + }; + c.name().as_str() == ssid.as_ref() && c_hw_address == hw_address + }) + { + *state = ActiveConnectionState::Deactivating; } - }) - .map(cosmic::Action::App); + tx + } else { + return Task::none(); + }; + if let Err(err) = tx.unbounded_send(network_manager::Request::Disconnect(ssid)) { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); + } } Message::Error(error) => { tracing::error!("error: {error:?}") @@ -1422,37 +1121,141 @@ impl cosmic::Application for CosmicNetworkApplet { *identity = new_identity; } } - Message::ConnectionAttemptFinished { - access_point, - success, - error, - } => { - if success { - self.failed_known_ssids.remove(access_point.ssid.as_ref()); - self.new_connection = None; - self.show_visible_networks = false; - } else { - if let Some(error) = error { - tracing::warn!("connect {} failed: {error}", access_point.ssid); - } - self.failed_known_ssids.insert(access_point.ssid.clone()); - self.new_connection = Some(NewConnectionState::Failure(access_point)); + Message::NetworkManager(event) => match event { + network_manager::Event::Init { + conn, + sender, + state, + } => { + self.nm_sender = Some(sender); + self.update_nm_state(state); + self.conn = Some(conn); } - return snapshot_task().map(cosmic::Action::App); - } - Message::NetworkEvent(event) => { - if matches!(event, NetworkEvent::NetworkManagerRestarted) { - tracing::debug!( - "NetworkManager restarted; refreshing network snapshot and secret agent" - ); - if let Some(mut tx) = self.secret_agent_reregister_tx.clone() { - if let Err(e) = tx.unbounded_send(()) { - tracing::warn!("secret agent re-registration task stopped: {e}"); - self.secret_agent_reregister_tx = None; + network_manager::Event::WiFiEnabled(_) + | network_manager::Event::WirelessAccessPoints + | network_manager::Event::ActiveConns => { + if let Some(conn) = self.conn.clone() { + return Task::future(async move { + let conn = conn.clone(); + NetworkManagerState::new(&conn).await + }) + .map(|res| match res { + Ok(s) => Message::UpdateState(s), + Err(err) => Message::Error(err.to_string()), + }) + .map(cosmic::Action::App); + } + } + network_manager::Event::RequestResponse { + mut state, + success, + req, + } => { + if let network_manager::Request::SelectAccessPoint( + ssid, + hw_address, + _network_type, + secret_tx, + ) = &req + { + let conn_match = self + .new_connection + .as_ref() + .is_some_and(|c| c.ssid() == ssid.as_ref() ); + + if conn_match && success { + if let Some(ActiveConnectionInfo::WiFi { state, .. }) = state + .active_conns + .iter_mut() + .find(|ap| { + let ap_hw_address = match ap { + ActiveConnectionInfo::Wired { hw_address, .. } + | ActiveConnectionInfo::WiFi { hw_address, .. } => { + HwAddress::from_str(&hw_address).unwrap() + } + ActiveConnectionInfo::Vpn { .. } => HwAddress::default(), + }; + ap.name().as_str() == ssid.as_ref()}) + { + *state = ActiveConnectionState::Activated; + } + self.failed_known_ssids.remove(ssid); + self.new_connection = None; + self.show_visible_networks = false; + } else if !matches!( + &self.new_connection, + Some(NewConnectionState::EnterPassword { .. }) + ) && !success { + self.failed_known_ssids.insert(ssid.clone()); } + } else if let network_manager::Request::Authenticate { + ssid, + identity: _, + password: _, + secret_tx, + interface + } = &req + { + if let Some(NewConnectionState::Waiting(access_point)) = + self.new_connection.as_ref() + { + if !success + && ssid.as_str() == access_point.ssid.as_ref() + { + self.new_connection = + Some(NewConnectionState::Failure(access_point.clone())); + } else { + self.show_visible_networks = false; + } + } else if let Some(NewConnectionState::EnterPassword { + access_point, .. + }) = self.new_connection.as_ref() + { + if success && ssid.as_str() == access_point.ssid.as_ref() { + self.new_connection = None; + self.show_visible_networks = false; + } + } + } else if self + .new_connection + .as_ref() + .map(NewConnectionState::ssid).is_some_and(|ssid| { + state.active_conns.iter().any(|c| + matches!(c, ActiveConnectionInfo::WiFi { name, state: ActiveConnectionState::Activated, .. } if ssid == name) + ) + }) { + self.new_connection = None; + self.show_visible_networks = false; + } + + if !matches!(req, network_manager::Request::Reload) + && matches!(state.connectivity, NmConnectivityState::Portal) + { + let mut browser = std::process::Command::new("xdg-open"); + browser.arg("http://204.pop-os.org/"); + + tokio::spawn(cosmic::process::spawn(browser)); + } + + self.update_nm_state(state); + } + + cosmic_settings_network_manager_subscription::Event::Devices => { + if let Some(conn) = self.conn.clone() { + return update_devices(conn).map(cosmic::Action::App); } } - return snapshot_task().map(cosmic::Action::App); + cosmic_settings_network_manager_subscription::Event::WiFiCredentials { + ssid, + password, + security_type, + } => {} + }, + Message::NetworkManagerConnect(connection) => { + return cosmic::task::batch(vec![ + self.connect(connection.clone()), + connection_settings(connection), + ]); } Message::PasswordUpdate(entered_pw) => { if let Some(NewConnectionState::EnterPassword { password, .. }) = @@ -1461,99 +1264,93 @@ impl cosmic::Application for CosmicNetworkApplet { *password = entered_pw; } } - Message::Snapshot(snapshot) => { - self.apply_snapshot(snapshot); + Message::UpdateState(network_manager_state) => { + self.update_nm_state(network_manager_state); + } + Message::UpdateDevices(device_infos) => { + self.nm_state.devices = device_infos.into_iter().map(Arc::new).collect(); } Message::WiFiEnable(enable) => { - self.nm_state.nm_state.wifi_enabled = enable; - return cosmic::task::future(async move { - match NmrsManager::new().await { - Ok(nm) => match nm.set_wireless_enabled(enable).await { - Ok(()) => Message::Refresh, - Err(e) => Message::Error(format!("set_wireless_enabled: {e}")), - }, - Err(e) => Message::Error(format!("nmrs init: {e}")), + if let Some(sender) = self.nm_sender.as_mut() { + if let Err(err) = + sender.unbounded_send(network_manager::Request::SetWiFi(enable)) + { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); } - }) - .map(cosmic::Action::App); + if let Err(err) = sender.unbounded_send(network_manager::Request::Reload) { + if err.is_disconnected() { + return system_conn().map(cosmic::Action::App); + } + + tracing::error!("{err:?}"); + } + } } Message::SecretAgent(agent_event) => match agent_event { - NmAgentEvent::RequestSecret { - connection_uuid, - connection_id, - setting, - responder, + nm_secret_agent::Event::RequestSecret { + uuid, + name, + description, + previous, + tx, + .. } => { - let description = (!connection_id.is_empty()).then_some(connection_id); - let known_vpn = self - .nm_state - .known_vpns - .contains_key(connection_uuid.as_str()); - - let mut consumed = false; - if let Some(state) = self.new_connection.as_mut() { match state { NewConnectionState::EnterPassword { access_point, .. } | NewConnectionState::Waiting(access_point) | NewConnectionState::Failure(access_point) => { - let matches_ssid = matches!( - &setting, - AgentSetting::WifiPsk { ssid } - if ssid == access_point.ssid.as_ref() - ); - let matches_uuid = self + if self .nm_state .ssid_to_uuid .get(access_point.ssid.as_ref()) - .is_some_and(|ap_uuid| { - ap_uuid.as_ref() == connection_uuid.as_str() - }); - - if matches_ssid || matches_uuid { + .is_some_and(|ap_uuid| ap_uuid.as_ref() == uuid.as_str()) + { *state = NewConnectionState::EnterPassword { access_point: access_point.clone(), - description: description.clone(), + description, identity: String::new(), password: String::new().into(), password_hidden: true, - }; + } } } } - } else if known_vpn { - let secret_keys = match &setting { - AgentSetting::Vpn { secret_keys } => secret_keys.clone(), - _ => Vec::new(), - }; + } else if self.nm_state.known_vpns.contains_key(uuid.as_str()) { self.nm_state.requested_vpn = Some(RequestedVpn { - uuid: connection_uuid.into(), + name, + uuid: uuid.into(), description, - password: SecureString::from(String::new()), + password: previous, password_hidden: true, - responder: responder.clone(), - secret_keys, + tx, }); - consumed = true; - } - - // The applet's Wi-Fi flow re-issues the password through - // `Authenticate` rather than the agent. Free NM with - // `NoSecrets` so it doesn't sit on a stalled GetSecrets call. - if !consumed { - return release_responder(responder); } } - NmAgentEvent::CancelGetSecrets => { + nm_secret_agent::Event::CancelGetSecrets { .. } => { self.new_connection = None; self.nm_state.requested_vpn = None; } - NmAgentEvent::Failed(error) => { - tracing::error!("Error from secret agent: {error}"); + nm_secret_agent::Event::Failed(error) => { + tracing::error!("Error from secret agent: {error:?}"); } }, + Message::KnownConnections(index_map) => { + self.nm_state.known_vpns = index_map; + } Message::Refresh => { - return snapshot_task().map(cosmic::Action::App); + if let Some(conn) = self.conn.clone() { + return Task::batch(vec![ + update_state(conn.clone()), + update_devices(conn.clone()), + load_vpns(conn), + ]) + .map(cosmic::Action::App); + } } Message::ToggleVPNPasswordVisibility => { if let Some(requested_vpn) = self.nm_state.requested_vpn.as_mut() { @@ -1561,30 +1358,12 @@ impl cosmic::Application for CosmicNetworkApplet { } } Message::ConnectVPNWithPassword => { - if let Some(RequestedVpn { - password, - responder, - secret_keys, - .. - }) = self.nm_state.requested_vpn.take() + if let Some(RequestedVpn { password, tx, .. }) = self.nm_state.requested_vpn.take() { return Task::future(async move { - let Some(responder) = responder.lock().await.take() else { - return Message::Refresh; - }; - - let mut secrets: HashMap = HashMap::new(); - let value = password.unsecure().to_owned(); - if secret_keys.is_empty() { - secrets.insert("password".to_owned(), value); - } else { - for key in secret_keys { - secrets.insert(key, value.clone()); - } - } - - if let Err(e) = responder.vpn_secrets(secrets).await { - tracing::error!("vpn secret reply failed: {e}"); + let mut guard = tx.lock().await; + if let Some(tx) = guard.take() { + let _ = tx.send(password); } Message::Refresh }) @@ -1597,15 +1376,7 @@ impl cosmic::Application for CosmicNetworkApplet { } } Message::CancelVPNConnection => { - if let Some(req) = self.nm_state.requested_vpn.take() { - return Task::future(async move { - if let Some(responder) = req.responder.lock().await.take() { - let _ = responder.cancel().await; - } - Message::NoOp - }) - .map(cosmic::Action::App); - } + self.nm_state.requested_vpn = None; } } Task::none() @@ -1629,20 +1400,16 @@ impl cosmic::Application for CosmicNetworkApplet { let mut known_wifi = Vec::new(); for conn in &self.nm_state.nm_state.active_conns { match conn { - ActiveConnectionInfo::Vpn { - name, - ip4_address, - ip6_address, - } => { + ActiveConnectionInfo::Vpn { name, ip_addresses } => { if self.active_device.as_ref().is_some_and(|d| { d.active_connection.as_ref().is_none_or(|a| a.0.id != *name) }) { continue; } - let mut info_col = Vec::with_capacity(3); - info_col.push(text::body(name).into()); - for elem in ip_address_elements(ip4_address, ip6_address) { - info_col.push(elem); + let mut ipv4 = Vec::with_capacity(ip_addresses.len() + 1); + ipv4.push(text::body(name).into()); + for addr in ip_addresses { + ipv4.push(text::caption(format!("{}: {}", fl!("ipv4"), addr)).into()); } vpn_ethernet_col = vpn_ethernet_col.push( column::with_capacity::(2) @@ -1650,13 +1417,13 @@ impl cosmic::Application for CosmicNetworkApplet { row::with_children([ Element::from( icon::icon( - icon::from_name("network-vpn-symbolic") + icon::from_name(self.icon_name.clone()) .symbolic(true) .into(), ) .size(40), ), - column::with_children(info_col).into(), + column::with_children(ipv4).into(), text::body(fl!("connected")) .width(Length::Fill) .align_x(Alignment::End) @@ -1674,19 +1441,20 @@ impl cosmic::Application for CosmicNetworkApplet { } ActiveConnectionInfo::Wired { name, - hw_address: _, + hw_address, speed, - ip4_address, - ip6_address, + ip_addresses, } => { if self.active_device.as_ref().is_some_and(|d| { d.active_connection.as_ref().is_none_or(|a| a.0.id != *name) }) { continue; } - let mut info_col = Vec::with_capacity(3); - info_col.push(text::body(name).into()); - info_col.extend(ip_address_elements(ip4_address, ip6_address)); + let mut ipv4 = Vec::with_capacity(ip_addresses.len() + 1); + ipv4.push(text::body(name).into()); + for addr in ip_addresses { + ipv4.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into()); + } let mut right_column = vec![text::body(fl!("connected")).into()]; @@ -1718,13 +1486,13 @@ impl cosmic::Application for CosmicNetworkApplet { row::with_children([ Element::from( icon::icon( - icon::from_name("network-wired-symbolic") + icon::from_name(self.icon_name.clone()) .symbolic(true) .into(), ) .size(40), ), - column::with_children(info_col).into(), + column::with_children(ipv4).into(), column::with_children(right_column) .width(Length::Fill) .align_x(Alignment::End) @@ -1742,8 +1510,7 @@ impl cosmic::Application for CosmicNetworkApplet { } ActiveConnectionInfo::WiFi { name, - ip4_address, - ip6_address, + ip_addresses, state, strength, hw_address, @@ -1753,7 +1520,10 @@ impl cosmic::Application for CosmicNetworkApplet { }) { continue; } - let ip_elements = ip_address_elements(ip4_address, ip6_address); + let mut ipv4 = Vec::with_capacity(ip_addresses.len()); + for addr in ip_addresses { + ipv4.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into()); + } let mut btn_content = vec![ icon::from_name(wifi_icon(*strength)) .size(24) @@ -1761,14 +1531,19 @@ impl cosmic::Application for CosmicNetworkApplet { .into(), column::with_children([ text::body(name).into(), - column::with_children(ip_elements).into(), + column::with_children(ipv4).into(), ]) .width(Length::Fill) .into(), ]; match state { ActiveConnectionState::Activating | ActiveConnectionState::Deactivating => { - btn_content.push(indeterminate_circular().size(24.0).into()); + btn_content.push( + icon::from_name("process-working-symbolic") + .size(24) + .symbolic(true) + .into(), + ); } ActiveConnectionState::Activated => btn_content.push( text::body(fl!("connected")) @@ -1786,7 +1561,7 @@ impl cosmic::Application for CosmicNetworkApplet { .icon_size(16) .on_press(Message::ResetFailedKnownSsid( name.clone(), - HwAddress::from_str(hw_address).unwrap_or_default(), + HwAddress::from_str(&hw_address).unwrap(), )) .into(), ); @@ -1801,7 +1576,7 @@ impl cosmic::Application for CosmicNetworkApplet { ) .on_press(Message::Disconnect( Arc::from(name.as_str()), - HwAddress::from_str(hw_address).unwrap_or_default(), + HwAddress::from_str(&hw_address).unwrap(), )), )]) .align_x(Alignment::Center), @@ -1914,7 +1689,7 @@ impl cosmic::Application for CosmicNetworkApplet { .nm_state .devices .iter() - .filter(|d| matches!(d.device_type, DeviceType::Wifi)) + .filter(|d| matches!(d.device_type, network_manager::devices::DeviceType::Wifi)) .collect::>(); if wireless_hw_devices.len() > 1 && self.active_device.is_none() { @@ -1958,16 +1733,14 @@ impl cosmic::Application for CosmicNetworkApplet { } for known in &self.nm_state.nm_state.known_access_points { - if matches!(known.state, DeviceState::Activated) { - continue; - } - if let Some(active_device) = self.active_device.as_ref() - && active_device + if let Some(active_device) = self.active_device.as_ref() { + if active_device .known_connections .iter() - .all(|c| c.id != *known.ssid) - { - continue; + .all(|c| &c.id != known.ssid.as_ref()) + { + continue; + } } let mut btn_content = Vec::with_capacity(2); let ssid = text::body(known.ssid.as_ref()).width(Length::Fill); @@ -1979,7 +1752,12 @@ impl cosmic::Application for CosmicNetworkApplet { .into(), ); btn_content.push(ssid.into()); - btn_content.push(indeterminate_circular().size(24.0).into()); + btn_content.push( + icon::from_name("process-working-symbolic") + .size(24) + .symbolic(true) + .into(), + ); } else if matches!(known.state, DeviceState::Unavailable) { btn_content.push( icon::from_name("network-wireless-disconnected-symbolic") @@ -2004,7 +1782,7 @@ impl cosmic::Application for CosmicNetworkApplet { .icon_size(16) .on_press(Message::ResetFailedKnownSsid( known.ssid.to_string(), - known.hw_address.clone(), + known.hw_address, )) .into(), ); @@ -2016,8 +1794,6 @@ impl cosmic::Application for CosmicNetworkApplet { .spacing(8), ); btn = match known.state { - // Activated entries are skipped above (shown in the active - // connections section instead), so no Disconnect arm is needed here. DeviceState::Failed | DeviceState::Unknown | DeviceState::Unmanaged @@ -2025,6 +1801,9 @@ impl cosmic::Application for CosmicNetworkApplet { | DeviceState::NeedAuth => { btn.on_press(Message::Connect(known.ssid.clone(), known.hw_address)) } + DeviceState::Activated => { + btn.on_press(Message::Disconnect(known.ssid.clone(), known.hw_address)) + } _ => btn, }; known_wifi.push(Element::from( @@ -2092,44 +1871,44 @@ impl cosmic::Application for CosmicNetworkApplet { ); content = content.push(id); - let is_enterprise = matches!(access_point.network_type, NetworkType::Eap); - let enter_password_col = cosmic::widget::column::with_capacity(4) - .push_maybe(is_enterprise.then(|| text::body(fl!("identity")))) - .push_maybe(is_enterprise.then(|| { - text_input::text_input("", identity).on_input(Message::IdentityUpdate) - })) - .push(text::body(fl!("enter-password"))) - .push_maybe(description.as_ref().map(|d| text::body(d.clone()))) - .push( - text_input::secure_input( - "", - password.unsecure(), - Some(Message::TogglePasswordVisibility), - *password_hidden, + let is_enterprise = matches!(access_point.network_type, NetworkType::EAP); + let enter_password_col = + cosmic::widget::column::with_capacity(4) + .push_maybe(is_enterprise.then(|| text::body(fl!("identity")))) + .push_maybe(is_enterprise.then(|| { + text_input::text_input("", identity) + .on_input(|i| Message::IdentityUpdate(i)) + })) + .push(text::body(fl!("enter-password"))) + .push_maybe(description.as_ref().map(|d| text::body(d.clone()))) + .push( + text_input::secure_input( + "", + password.unsecure(), + Some(Message::TogglePasswordVisibility), + *password_hidden, + ) + .id(SECURE_INPUT_WIFI.clone()) + .on_input(|s| Message::PasswordUpdate(SecureString::from(s))) + .on_paste(|s| Message::PasswordUpdate(SecureString::from(s))) + .on_submit(|_| Message::ConnectWithPassword), ) - .id(SECURE_INPUT_WIFI.clone()) - .on_input(|s| Message::PasswordUpdate(SecureString::from(s))) - .on_paste(|s| Message::PasswordUpdate(SecureString::from(s))) - .on_submit(|_| Message::ConnectWithPassword), - ) - .push_maybe( - access_point.wps_push.then(|| { + .push_maybe(access_point.wps_push.then(|| { container(text::body(fl!("router-wps-button"))).padding(8) - }), - ) - .push( - row::with_children([ - Element::from( - button::standard(fl!("cancel")) - .on_press(Message::CancelNewConnection), - ), - Element::from( - button::suggested(fl!("connect")) - .on_press(Message::ConnectWithPassword), - ), - ]) - .spacing(24), - ); + })) + .push( + row::with_children([ + Element::from( + button::standard(fl!("cancel")) + .on_press(Message::CancelNewConnection), + ), + Element::from( + button::suggested(fl!("connect")) + .on_press(Message::ConnectWithPassword), + ), + ]) + .spacing(24), + ); let col = padded_control(enter_password_col.spacing(8).align_x(Alignment::Center)) .align_x(Alignment::Center); @@ -2150,7 +1929,10 @@ impl cosmic::Application for CosmicNetworkApplet { let connecting = padded_control( row::with_children([ Element::from(id), - indeterminate_circular().size(24.0).into(), + icon::from_name("process-working-symbolic") + .size(24) + .symbolic(true) + .into(), ]) .spacing(8), ); @@ -2205,7 +1987,7 @@ impl cosmic::Application for CosmicNetworkApplet { .filter(|ap| { let among_active = self.nm_state.nm_state.active_conns.iter().any(|a| { let hw_address = active_conn_hw_address(a); - ap.ssid.as_ref() == a.name() && ap.hw_address == hw_address + ap.ssid.as_ref() == &a.name() && ap.hw_address == hw_address }); let among_known = self.nm_state @@ -2272,9 +2054,7 @@ impl cosmic::Application for CosmicNetworkApplet { fn active_conn_hw_address(conn: &ActiveConnectionInfo) -> HwAddress { match conn { ActiveConnectionInfo::Wired { hw_address, .. } - | ActiveConnectionInfo::WiFi { hw_address, .. } => { - HwAddress::from_str(hw_address).unwrap_or_default() - } + | ActiveConnectionInfo::WiFi { hw_address, .. } => HwAddress::from_str(hw_address).unwrap(), ActiveConnectionInfo::Vpn { .. } => HwAddress::default(), } } diff --git a/cosmic-applet-network/src/lib.rs b/cosmic-applet-network/src/lib.rs index f1ce1c6e..7d5414a5 100644 --- a/cosmic-applet-network/src/lib.rs +++ b/cosmic-applet-network/src/lib.rs @@ -3,6 +3,7 @@ mod app; mod config; mod localize; +mod utils; use crate::localize::localize; diff --git a/cosmic-applet-network/src/utils.rs b/cosmic-applet-network/src/utils.rs new file mode 100644 index 00000000..f802010f --- /dev/null +++ b/cosmic-applet-network/src/utils.rs @@ -0,0 +1,18 @@ +use futures_util::future::select; + +/// Spawn a background tasks and forward its messages +pub fn forward_event_loop + Send + 'static>( + event_loop: impl FnOnce(async_fn_stream::StreamEmitter) -> T + Send + 'static, +) -> (tokio::sync::oneshot::Sender<()>, cosmic::Task) { + let (cancel_tx, cancel_rx) = tokio::sync::oneshot::channel::<()>(); + + let task = cosmic::Task::stream(async_fn_stream::fn_stream(|emitter| async move { + select( + std::pin::pin!(cancel_rx), + std::pin::pin!(event_loop(emitter)), + ) + .await; + })); + + (cancel_tx, task) +} diff --git a/cosmic-applet-notifications/Cargo.toml b/cosmic-applet-notifications/Cargo.toml index 04d048e0..094cfa14 100644 --- a/cosmic-applet-notifications/Cargo.toml +++ b/cosmic-applet-notifications/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-notifications" -version = "1.9.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -8,7 +8,7 @@ license = "GPL-3.0-only" cosmic-notifications-util = { git = "https://github.com/pop-os/cosmic-notifications" } cosmic-notifications-config = { git = "https://github.com/pop-os/cosmic-notifications" } anyhow.workspace = true -cosmic.workspace = true +libcosmic.workspace = true tokio.workspace = true # cosmic-notifications-util = { path = "../../cosmic-notifications-daemon/cosmic-notifications-util" } # cosmic-notifications-config = { path = "../../cosmic-notifications-daemon/cosmic-notifications-config" } diff --git a/cosmic-applet-notifications/i18n/da/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/da/cosmic_applet_notifications.ftl index 8f74f85a..e69de29b 100644 --- a/cosmic-applet-notifications/i18n/da/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/da/cosmic_applet_notifications.ftl @@ -1,19 +0,0 @@ -show-more = Vis { $more } mere -clear-all = Ryd alle notifikationer -notification-settings = Notifikationsindstillinger... -no-notifications = Ingen notifikationer -do-not-disturb = Forstyr Ikke -show-less = Vis mindre -clear-group = Ryd gruppe -hours-ago = - { $duration -> - [0] Netop nu - [one] 1 time siden - *[other] { $duration } timer siden - } -minutes-ago = - { $duration -> - [0] Netop nu - [one] 1 minut siden - *[other] { $duration } minutter siden - } diff --git a/cosmic-applet-notifications/i18n/de/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/de/cosmic_applet_notifications.ftl index e40af6aa..6f103ed6 100644 --- a/cosmic-applet-notifications/i18n/de/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/de/cosmic_applet_notifications.ftl @@ -15,5 +15,5 @@ show-more = { $more } weitere anzeigen clear-group = Gruppe leeren clear-all = Alle Benachrichtigungen leeren do-not-disturb = Nicht stören -notification-settings = Benachrichtigungseinstellungen ... +notification-settings = Benachrichtigungseinstellungen... no-notifications = Keine Benachrichtigungen diff --git a/cosmic-applet-notifications/i18n/el/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/el/cosmic_applet_notifications.ftl index 56feb284..e69de29b 100644 --- a/cosmic-applet-notifications/i18n/el/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/el/cosmic_applet_notifications.ftl @@ -1,19 +0,0 @@ -hours-ago = - { $duration -> - [0] Μόλις τώρα - [one] Πριν από 1 ώρα - *[other] Πριν από { $duration } ώρες - } -show-more = Εμφάνιση { $more } ακόμη -clear-all = Απαλοιφή όλων των ειδοποιήσεων -notification-settings = Ρυθμίσεις ειδοποιήσεων... -no-notifications = Καμία ειδοποίηση -do-not-disturb = Μην ενοχλείτε -show-less = Εμφάνιση λιγότερων -clear-group = Απαλοιφή ομάδας -minutes-ago = - { $duration -> - [0] Μόλις τώρα - [one] Πριν από 1 λεπτό - *[other] Πριν από { $duration } λεπτά - } diff --git a/cosmic-applet-notifications/i18n/fil/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/fil/cosmic_applet_notifications.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-notifications/i18n/gl/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/gl/cosmic_applet_notifications.ftl deleted file mode 100644 index 411d92c1..00000000 --- a/cosmic-applet-notifications/i18n/gl/cosmic_applet_notifications.ftl +++ /dev/null @@ -1,19 +0,0 @@ -hours-ago = - { $duration -> - [0] Xusto agora - [one] Hai 1 hora - *[other] Hai { $duration } horas - } -minutes-ago = - { $duration -> - [0] Xusto agora - [one] Hai 1 minuto - *[other] Hai { $duration } minutos - } -show-less = Mostrar menos -show-more = Mostrar { $more } máis -clear-group = Limpar grupo -clear-all = Limpar todas as notificacións -do-not-disturb = Non Molestar -notification-settings = Configuración das notificacións... -no-notifications = Sen notificacións diff --git a/cosmic-applet-notifications/i18n/hu/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/hu/cosmic_applet_notifications.ftl index 0ff88aa1..ec1f5a91 100644 --- a/cosmic-applet-notifications/i18n/hu/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/hu/cosmic_applet_notifications.ftl @@ -1,14 +1,14 @@ hours-ago = { $duration -> - [0] Épp most - [one] 1 órája - *[other] { $duration } órája + [0] Most + [one] 1 órával ezelőtt + *[other] { $duration } órával ezelőtt } minutes-ago = { $duration -> - [0] Épp most - [one] 1 perce - *[other] { $duration } perce + [0] Most + [one] 1 perccel ezelőtt + *[other] { $duration } perccel ezelőtt } show-less = Kevesebb megjelenítése show-more = { $more } további megjelenítése diff --git a/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl index b7a7578a..e69de29b 100644 --- a/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl @@ -1,19 +0,0 @@ -hours-ago = - { $duration -> - [0] Niha - [one] 1 demjimêr berê - *[other] { $duration } demjimêr berê - } -minutes-ago = - { $duration -> - [0] Niha - [one] 1 xulek berê - *[other] { $duration } xulek berê - } -show-less = Kêmtir nîşan bide -show-more = Bêtir { $more } nîşan bide -clear-group = Komê pak bike -clear-all = Hemû agahdariyan pak bike -do-not-disturb = Rawestandina balkêşiyê -notification-settings = Sazkariyên agahdariyê.... -no-notifications = Agahdarî tune ne diff --git a/cosmic-applet-notifications/i18n/lo/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/lo/cosmic_applet_notifications.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-notifications/i18n/sat/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/sat/cosmic_applet_notifications.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-notifications/i18n/sr/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/sr/cosmic_applet_notifications.ftl index 39408d17..e69de29b 100644 --- a/cosmic-applet-notifications/i18n/sr/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/sr/cosmic_applet_notifications.ftl @@ -1,19 +0,0 @@ -show-more = Прикажи још { $more } -clear-all = Очисти сва обавештења -notification-settings = Подешавања обавештења... -no-notifications = Без обавештења -do-not-disturb = Не узнемиравај -show-less = Прикажи мање -clear-group = Очисти групу -hours-ago = - { $duration -> - [0] Управо сада - [one] Пре 1 сата - *[other] Пре { $duration } сати - } -minutes-ago = - { $duration -> - [0] Управо сада - [one] Пре 1 минута - *[other] Пре { $duration } минута - } diff --git a/cosmic-applet-notifications/src/lib.rs b/cosmic-applet-notifications/src/lib.rs index 4041d486..438696b9 100644 --- a/cosmic-applet-notifications/src/lib.rs +++ b/cosmic-applet-notifications/src/lib.rs @@ -78,7 +78,7 @@ enum Message { CardsToggled(String, bool), Token(TokenUpdate), OpenSettings, - Surface(surface::Action), + Surface(surface::Action), } impl cosmic::Application for Notifications { @@ -157,23 +157,18 @@ impl cosmic::Application for Notifications { if let Some(p) = self.popup.take() { return destroy_popup(p); } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = window::Id::unique(); - app.popup.replace(new_id); + let new_id = window::Id::unique(); + self.popup.replace(new_id); - let popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - popup_settings - }, + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, None, - )); + None, + None, + ); + + return get_popup(popup_settings); } } Message::DoNotDisturb(b) => { @@ -367,7 +362,9 @@ impl cosmic::Application for Notifications { } } Message::Surface(a) => { - return cosmic::task::message(cosmic::Action::Surface(a)); + return cosmic::task::message(cosmic::Action::Cosmic( + cosmic::app::Action::Surface(a), + )); } } self.update_icon(); diff --git a/cosmic-applet-osk/Cargo.toml b/cosmic-applet-osk/Cargo.toml deleted file mode 100644 index 1aa13b59..00000000 --- a/cosmic-applet-osk/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "cosmic-applet-osk" -version = "1.9.0" -edition = "2024" -license = "GPL-3.0-only" - -[dependencies] -cosmic-osk-config.workspace = true -cosmic.workspace = true -tracing.workspace = true -tracing-subscriber.workspace = true -tracing-log.workspace = true diff --git a/cosmic-applet-osk/data/com.system76.CosmicAppletOsk.desktop b/cosmic-applet-osk/data/com.system76.CosmicAppletOsk.desktop deleted file mode 100644 index 0624bdc9..00000000 --- a/cosmic-applet-osk/data/com.system76.CosmicAppletOsk.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Name=On-screen Keyboard Button -Comment=Open the on-screen keyboard -Type=Application -Exec=cosmic-applet-osk -Terminal=false -Categories=COSMIC; -Keywords=COSMIC;Applet;OSK;Keyboard; -Icon=input-keyboard-symbolic -StartupNotify=true -NoDisplay=true -X-CosmicApplet=true -X-OverflowPriority=10 diff --git a/cosmic-applet-osk/src/lib.rs b/cosmic-applet-osk/src/lib.rs deleted file mode 100644 index a1597757..00000000 --- a/cosmic-applet-osk/src/lib.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: GPL-3.0-only - -use cosmic::{Task, app, cosmic_config::CosmicConfigEntry, iced}; -use cosmic_osk_config::Config; - -struct Button { - core: cosmic::app::Core, -} - -#[derive(Debug, Clone)] -enum Msg { - Press, -} - -impl cosmic::Application for Button { - type Message = Msg; - type Executor = cosmic::SingleThreadExecutor; - type Flags = (); - const APP_ID: &'static str = "com.system76.CosmicAppletOsk"; - - fn init(core: cosmic::app::Core, _: ()) -> (Self, app::Task) { - (Self { core }, Task::none()) - } - - fn core(&self) -> &cosmic::app::Core { - &self.core - } - - fn core_mut(&mut self) -> &mut cosmic::app::Core { - &mut self.core - } - - fn style(&self) -> Option { - Some(cosmic::applet::style()) - } - - fn update(&mut self, message: Msg) -> app::Task { - match message { - Msg::Press => match Config::handler() { - Ok(handler) => { - let mut config = match Config::get_entry(&handler) { - Ok(config) => config, - Err((errs, config)) => { - tracing::warn!("failed to parse OSK config: {:?}", errs); - config - } - }; - if let Err(err) = config.set_always_shown(&handler, !config.always_shown) { - tracing::error!("failed to set OSK always_shown config: {}", err); - } - } - Err(err) => { - tracing::error!("failed to create OSK config handler: {}", err); - } - }, - } - Task::none() - } - - fn view(&self) -> cosmic::Element<'_, Msg> { - self.core - .applet - .icon_button("input-keyboard-symbolic") - .on_press_down(Msg::Press) - .into() - } -} - -pub fn run() -> iced::Result { - cosmic::applet::run::