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 52958bc6..1a265c94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" @@ -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.0", + "bitflags 2.11.0", "cc", "jni", "libc", @@ -182,10 +187,26 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.103" +name = "annotate-snippets" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +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.4", + "rand 0.9.2", "raw-window-handle", "serde", "serde_repr", @@ -259,7 +286,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.4", + "rand 0.9.2", "serde", "serde_repr", "tokio", @@ -374,7 +401,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -409,7 +436,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -467,21 +494,21 @@ dependencies = [ [[package]] name = "auto_enums" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4487600931c9a89f8db7ffbdf3fbdd45bb7bd85e26861f659a463cd0dff966" +checksum = "65398a2893f41bce5c9259f6e1a4f03fbae40637c1bdc755b4f387f48c613b03" dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 2.0.118", + "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" @@ -498,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" @@ -521,9 +567,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" dependencies = [ "serde_core", ] @@ -536,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]] @@ -591,7 +646,7 @@ dependencies = [ "libc", "log", "macaddr", - "nix", + "nix 0.29.0", "num-derive", "num-traits", "pin-project", @@ -605,32 +660,23 @@ dependencies = [ [[package]] name = "borsh" -version = "1.7.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" +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.12.3" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", - "serde_core", + "serde", ] [[package]] @@ -642,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" @@ -678,7 +717,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -689,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" @@ -709,7 +748,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "polling", "rustix 1.1.4", "slab", @@ -729,15 +768,43 @@ dependencies = [ ] [[package]] -name = "cc" -version = "1.2.66" +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" +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]] @@ -754,9 +821,9 @@ 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", @@ -764,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" @@ -776,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", @@ -785,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" @@ -859,15 +958,24 @@ dependencies = [ [[package]] name = "configparser" -version = "3.2.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46dec724fd22199ebde05033a0cbae453bc3b1ecff11eb6a6bb3eec4b90c6a4" +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" @@ -925,7 +1033,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "core-foundation 0.10.1", "libc", ] @@ -941,7 +1049,7 @@ dependencies = [ [[package]] name = "cosmic-app-list" -version = "1.3.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-app-list-config", @@ -952,10 +1060,10 @@ 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", + "rustc-hash 2.1.2", "rustix 1.1.4", "switcheroo-control", "tokio", @@ -968,15 +1076,15 @@ dependencies = [ [[package]] name = "cosmic-app-list-config" -version = "1.3.0" +version = "1.0.2" dependencies = [ - "libcosmic-yoda", + "libcosmic", "serde", ] [[package]] name = "cosmic-applet-a11y" -version = "1.3.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -985,7 +1093,7 @@ dependencies = [ "cosmic-settings-accessibility-subscription", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -995,14 +1103,12 @@ dependencies = [ [[package]] name = "cosmic-applet-audio" -version = "1.3.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", @@ -1013,25 +1119,24 @@ dependencies = [ "url", "urlencoding", "zbus", - "zlink", ] [[package]] name = "cosmic-applet-battery" -version = "1.3.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", @@ -1043,7 +1148,7 @@ dependencies = [ [[package]] name = "cosmic-applet-bluetooth" -version = "1.3.0" +version = "1.0.2" dependencies = [ "anyhow", "bluer", @@ -1051,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", @@ -1062,14 +1167,12 @@ dependencies = [ [[package]] name = "cosmic-applet-input-sources" -version = "1.3.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", @@ -1080,14 +1183,14 @@ dependencies = [ [[package]] name = "cosmic-applet-minimize" -version = "1.3.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.4", "tokio", @@ -1098,29 +1201,34 @@ dependencies = [ [[package]] name = "cosmic-applet-network" -version = "1.3.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.0", - "libcosmic-yoda", - "nmrs", + "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.3.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-notifications-config", @@ -1128,7 +1236,7 @@ dependencies = [ "futures-util", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1140,11 +1248,11 @@ dependencies = [ [[package]] name = "cosmic-applet-power" -version = "1.3.0" +version = "1.0.2" dependencies = [ "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "logind-zbus", "rust-embed", "rustix 1.1.4", @@ -1157,11 +1265,11 @@ dependencies = [ [[package]] name = "cosmic-applet-status-area" -version = "1.3.0" +version = "1.0.2" dependencies = [ "futures", - "libcosmic-yoda", - "rustc-hash 2.1.3", + "libcosmic", + "rustc-hash 2.1.2", "serde", "tokio", "tracing", @@ -1172,7 +1280,7 @@ dependencies = [ [[package]] name = "cosmic-applet-tiling" -version = "1.3.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -1180,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", @@ -1191,14 +1299,14 @@ dependencies = [ [[package]] name = "cosmic-applet-time" -version = "1.3.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", @@ -1211,14 +1319,14 @@ dependencies = [ [[package]] name = "cosmic-applet-workspaces" -version = "1.3.0" +version = "1.0.2" dependencies = [ "anyhow", "cosmic-client-toolkit", "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic-yoda", + "libcosmic", "rust-embed", "tokio", "tracing", @@ -1228,7 +1336,7 @@ dependencies = [ [[package]] name = "cosmic-applets" -version = "1.3.0" +version = "1.0.2" dependencies = [ "cosmic-app-list", "cosmic-applet-a11y", @@ -1245,7 +1353,7 @@ dependencies = [ "cosmic-applet-time", "cosmic-applet-workspaces", "cosmic-panel-button", - "libcosmic-yoda", + "libcosmic", "tracing", "tracing-log", "tracing-subscriber", @@ -1254,7 +1362,7 @@ dependencies = [ [[package]] name = "cosmic-applets-config" -version = "1.3.0" +version = "1.0.2" dependencies = [ "cosmic-config", "serde", @@ -1263,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.0", + "bitflags 2.11.0", "cosmic-protocols", "libc", "smithay-client-toolkit", @@ -1274,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", @@ -1284,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", @@ -1293,7 +1404,7 @@ dependencies = [ "iced_futures", "known-folders", "notify", - "ron 0.12.2", + "ron 0.12.1", "serde", "tokio", "tracing", @@ -1304,27 +1415,42 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "quote", - "syn 2.0.118", + "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", + "memmap2 0.9.10", "thiserror 2.0.18", "tracing", "xdg", @@ -1333,6 +1459,7 @@ dependencies = [ [[package]] name = "cosmic-notifications-config" version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-notifications#6046bb29d570161196ab98d60806f6d6489df7a6" dependencies = [ "cosmic-config", "serde", @@ -1341,9 +1468,10 @@ dependencies = [ [[package]] name = "cosmic-notifications-util" version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-notifications#6046bb29d570161196ab98d60806f6d6489df7a6" dependencies = [ "fast_image_resize", - "libcosmic-yoda", + "libcosmic", "serde", "tl", "tracing", @@ -1353,11 +1481,11 @@ dependencies = [ [[package]] name = "cosmic-panel-button" -version = "1.3.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", @@ -1366,7 +1494,8 @@ dependencies = [ [[package]] name = "cosmic-panel-config" -version = "1.3.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel#d518c7d25ef96f1a9696aa8cce008656bf66ece4" dependencies = [ "anyhow", "cosmic-config", @@ -1377,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.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1392,7 +1536,8 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" -version = "1.7.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1405,7 +1550,8 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" -version = "1.7.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1416,33 +1562,21 @@ dependencies = [ ] [[package]] -name = "cosmic-settings-audio-client" -version = "1.0.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.0.0" -dependencies = [ - "dirs", - "ron 0.12.2", - "serde", - "zlink", ] [[package]] name = "cosmic-settings-config" version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#716da6d6af0b252e2f78aba2ad72ee19ae0241e0" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1454,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.7.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "futures", "iced_futures", @@ -1471,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.7.0" +version = "1.0.7" +source = "git+https://github.com/pop-os/cosmic-settings#3639bafcfa3b27fd6a8a9bca7e77589b903975e8" dependencies = [ "futures", "iced_futures", @@ -1486,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.0", + "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", @@ -1504,21 +1676,20 @@ 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.18", @@ -1526,9 +1697,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1544,9 +1715,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -1557,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]] @@ -1592,6 +1765,12 @@ dependencies = [ "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" @@ -1616,7 +1795,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.118", + "syn", "synstructure", ] @@ -1661,7 +1840,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn", ] [[package]] @@ -1675,7 +1854,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn", ] [[package]] @@ -1688,7 +1867,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn", ] [[package]] @@ -1699,7 +1878,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -1710,7 +1889,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -1721,7 +1900,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core 0.23.0", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -1732,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]] @@ -1763,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.118", -] - -[[package]] -name = "defmt-parser" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" -dependencies = [ - "thiserror 2.0.18", -] - [[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" @@ -1812,7 +1992,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -1823,18 +2003,18 @@ checksum = "362f47930db19fe7735f527e6595e4900316b893ebf6d48ad3d31be928d57dd6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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]] @@ -1864,7 +2044,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1872,13 +2052,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -1893,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.0", + "bitflags 2.11.0", "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit", @@ -1919,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" @@ -1926,21 +2121,31 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" dependencies = [ - "bitflags 2.13.0", + "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", + "drm-sys 0.8.1", "rustix 1.1.4", ] @@ -1950,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" @@ -1968,9 +2183,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.16.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "endi" @@ -1996,7 +2211,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -2069,9 +2284,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fast_image_resize" -version = "6.0.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dd43e5011e8d8411a3215a0d57a2ec5c68282fb90eb5d7221fab0113442174" +checksum = "fbc7fe45cf92b43817ff62a3723e862b85bd1d06288f63007f7645d1d2f7a060" dependencies = [ "cfg-if", "document-features", @@ -2100,7 +2315,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -2171,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", @@ -2216,9 +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" +checksum = "2d9237c6d82152100c691fb77ea18037b402bcc7257d2c876a4ffac81bc22a1c" dependencies = [ "bytemuck", ] @@ -2240,7 +2455,7 @@ checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "slotmap", "tinyvec", "ttf-parser", @@ -2264,7 +2479,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -2304,7 +2519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6d3a3635983a889f065aa9ce760384713f23a9b4a04f696f86c39a5d7a6a5a" dependencies = [ "indexmap 2.14.0", - "nom", + "nom 8.0.0", ] [[package]] @@ -2318,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", @@ -2333,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", @@ -2343,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", @@ -2360,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" @@ -2379,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.5", + "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", @@ -2423,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" @@ -2448,13 +2677,15 @@ 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]] @@ -2504,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" @@ -2526,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.18", - "windows 0.62.2", + "thiserror 1.0.69", + "windows 0.58.0", ] [[package]] @@ -2545,7 +2799,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2556,14 +2810,14 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.13.0", + "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" @@ -2593,10 +2847,10 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "bytemuck", "core_maths", - "read-fonts 0.37.0", + "read-fonts", "smallvec", ] @@ -2621,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" @@ -2662,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.6", - "serde", -] - [[package]] name = "hexf-parse" version = "0.2.1" @@ -2680,12 +2921,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] -name = "hybrid-array" -version = "0.4.13" +name = "hkdf" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" +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]] @@ -2738,7 +2988,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.118", + "syn", "unic-langid", ] @@ -2752,7 +3002,7 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -2782,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", @@ -2803,6 +3053,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "accesskit", "accesskit_winit", @@ -2811,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.0", - "build_helpers", + "bitflags 2.11.0", "bytes", "cosmic-client-toolkit", "dnd", @@ -2824,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.18", - "unicode-segmentation", "web-time", "window_clipboard", ] @@ -2836,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", @@ -2845,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", @@ -2858,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.0", + "bitflags 2.11.0", "bytemuck", "cosmic-text", "half", @@ -2870,7 +3123,7 @@ dependencies = [ "log", "lyon_path", "raw-window-handle", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", ] @@ -2878,6 +3131,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_runtime", @@ -2886,6 +3140,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2897,8 +3152,8 @@ dependencies = [ [[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", @@ -2912,6 +3167,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bytemuck", "cosmic-text", @@ -2920,7 +3176,7 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "softbuffer", "tiny-skia", ] @@ -2928,9 +3184,10 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ - "bitflags 2.13.0", - "build_helpers", + "as-raw-xcb-connection", + "bitflags 2.11.0", "bytemuck", "cosmic-client-toolkit", "cryoglyph", @@ -2943,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.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", @@ -2965,7 +3224,7 @@ dependencies = [ "log", "num-traits", "ouroboros", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", "window_clipboard", @@ -2974,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", @@ -2986,7 +3245,7 @@ dependencies = [ "iced_runtime", "log", "raw-window-handle", - "rustc-hash 2.1.3", + "rustc-hash 2.1.2", "rustix 0.38.44", "thiserror 2.0.18", "wasm-bindgen-futures", @@ -3075,9 +3334,9 @@ checksum = "846b0857ca091204be3c874bc93daaf89d4777e8d2d20b0d3ffe8f671d98014b" [[package]] name = "icu_collator" -version = "2.2.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbdf98e5e0aa827770acee171ebb568aaab975a36b56afdb5fd0e2f525750bb" +checksum = "b521b92a2666061ddda902769d8a4cf730b5c9529a845cc1b69770b12a6c9a71" dependencies = [ "icu_collator_data", "icu_collections", @@ -3402,6 +3661,12 @@ 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 = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -3421,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", @@ -3444,15 +3709,6 @@ dependencies = [ "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" @@ -3487,38 +3743,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.1", + "hashbrown 0.17.0", "serde", "serde_core", ] [[package]] name = "inotify" -version = "0.11.4" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "153be1941a183ec9ccd095ddbe17a8b8d435ef6c76e9e02451b933c3999af2c8" +checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.13.0", + "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.0", + "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", @@ -3567,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" @@ -3581,36 +3865,35 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.32" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961d16382652bfdd8c6f68b223b26a8c93e0d475c672f414411db31c6c5c900e" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" dependencies = [ - "defmt", "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", - "windows-link 0.2.1", + "windows-sys 0.61.2", ] [[package]] name = "jiff-static" -version = "0.2.32" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0879bd39df99c4c5e2c6615ccc026391a423dde10532c573e6086eb94a802cc" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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" @@ -3648,7 +3931,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn 2.0.118", + "syn", ] [[package]] @@ -3676,27 +3959,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.118", + "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.103" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ "cfg-if", "futures-util", + "once_cell", "wasm-bindgen", ] @@ -3715,7 +3999,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "serde", ] @@ -3747,9 +4031,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.2.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -3757,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.0", + "bitflags 1.3.2", "libc", ] @@ -3793,19 +4077,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "libc" -version = "0.2.186" +name = "leb128fmt" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +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", @@ -3815,7 +4105,6 @@ dependencies = [ "cosmic-theme", "css-color", "derive_setters", - "enumflags2", "float-cmp 0.10.0", "freedesktop-desktop-entry", "futures", @@ -3831,7 +4120,6 @@ dependencies = [ "iced_widget", "iced_winit", "image", - "image-extras", "jiff", "libc", "log", @@ -3839,11 +4127,11 @@ dependencies = [ "palette", "phf 0.13.1", "rfd", - "ron 0.12.2", + "ron 0.12.1", "rust-embed", "rustix 1.1.4", "serde", - "shlex 1.3.0", + "shlex", "slotmap", "taffy", "thiserror 2.0.18", @@ -3881,14 +4169,42 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.18" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "libc", "plain", - "redox_syscall 0.9.0", + "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]] @@ -3922,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" @@ -3970,9 +4292,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "logind-zbus" @@ -3986,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" @@ -4002,9 +4324,9 @@ dependencies = [ [[package]] name = "lyon_algorithms" -version = "1.0.20" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8575c0d003ae459399623c4def180c63b77f343b1a7fee64f249b349e7699a31" +checksum = "9815fac08e6fd96733a11dce4f9d15a3f338e96a2e2311ee21e1b738efc2bc0f" dependencies = [ "lyon_path", "num-traits", @@ -4068,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" @@ -4083,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", ] @@ -4101,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.0", + "bitflags 2.11.0", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -4117,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", ] @@ -4128,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" @@ -4149,9 +4468,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", @@ -4172,6 +4491,7 @@ dependencies = [ [[package]] name = "mpris2-zbus" version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ "futures-util", "jiff", @@ -4189,13 +4509,13 @@ 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.0", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -4219,7 +4539,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "jni-sys 0.3.1", "log", "ndk-sys", @@ -4249,30 +4569,40 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "libc", ] [[package]] -name = "nmrs" -version = "3.5.2" +name = "nix" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa84a0ad51eda83c8817099a0b613847599c712d049e89d892cca53ed6c4a337" +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", - "bitflags 2.13.0", - "futures", - "futures-timer", - "log", - "serde", - "thiserror 2.0.18", - "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]] @@ -4290,7 +4620,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "fsevent-sys", "inotify", "kqueue", @@ -4308,7 +4638,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", ] [[package]] @@ -4321,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" @@ -4344,7 +4697,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -4356,6 +4709,17 @@ 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" @@ -4396,9 +4760,15 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.118", + "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" @@ -4450,7 +4820,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -4466,7 +4836,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -4479,7 +4849,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4491,7 +4861,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "objc2 0.6.4", @@ -4503,7 +4873,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "libc", "objc2-core-foundation", ] @@ -4526,7 +4896,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "objc2-core-foundation", "objc2-core-graphics", ] @@ -4543,7 +4913,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -4555,7 +4925,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -4567,7 +4937,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4579,7 +4949,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -4592,7 +4962,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "objc2 0.6.4", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -4621,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", @@ -4669,7 +5039,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -4703,7 +5073,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -4775,7 +5145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.6", + "rand 0.8.5", ] [[package]] @@ -4798,7 +5168,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -4811,7 +5181,7 @@ dependencies = [ "phf_shared 0.13.1", "proc-macro2", "quote", - "syn 2.0.118", + "syn", "uncased", ] @@ -4842,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.118", + "syn", ] [[package]] @@ -4884,10 +5254,38 @@ dependencies = [ ] [[package]] -name = "pkg-config" -version = "0.3.33" +name = "pipewire" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +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" @@ -4914,7 +5312,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "crc32fast", "fdeflate", "flate2", @@ -4949,9 +5347,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ "portable-atomic", ] @@ -4988,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" @@ -5016,7 +5424,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -5036,22 +5444,43 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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" @@ -5061,18 +5490,28 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.39.4" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +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.46" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -5091,35 +5530,23 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha 0.3.1", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +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" @@ -5135,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" @@ -5177,42 +5601,22 @@ dependencies = [ "font-types", ] -[[package]] -name = "read-fonts" -version = "0.39.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81" -dependencies = [ - "bytemuck", - "font-types", -] - -[[package]] -name = "redox_event" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15" -dependencies = [ - "bitflags 2.13.0", - "libredox", -] - [[package]] name = "redox_syscall" version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", ] [[package]] name = "redox_syscall" -version = "0.9.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", ] [[package]] @@ -5243,14 +5647,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] name = "regex" -version = "1.13.0" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -5260,9 +5664,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.15" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -5271,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" @@ -5338,7 +5742,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", - "bitflags 2.13.0", + "bitflags 2.11.0", "serde", "serde_derive", "unicode-ident", @@ -5346,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.0", + "bitflags 2.11.0", "once_cell", "serde", "serde_derive", @@ -5366,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", @@ -5377,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.118", + "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", @@ -5407,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" @@ -5426,7 +5829,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -5439,7 +5842,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -5448,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" @@ -5458,7 +5861,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "bytemuck", "core_maths", "log", @@ -5470,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" @@ -5529,11 +5926,30 @@ checksum = "1dd3accc0f3f4bbaf2c9e1957a030dc582028130c67660d44c0a0345a22ca69b" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.11", + "memmap2 0.9.10", "smithay-client-toolkit", "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]] name = "secure-string" version = "0.3.0" @@ -5595,14 +6011,14 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap 2.14.0", "itoa", @@ -5620,17 +6036,25 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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.21.0" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ "base64", - "bs58", "chrono", "hex", "indexmap 1.9.3", @@ -5645,27 +6069,21 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.21.0" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.118", + "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", @@ -5687,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" @@ -5736,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" @@ -5747,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.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564" -dependencies = [ - "bytemuck", - "read-fonts 0.39.2", + "read-fonts", ] [[package]] @@ -5777,9 +6179,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay-client-toolkit" @@ -5787,14 +6189,14 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "bitflags 2.13.0", + "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.4", "thiserror 2.0.18", @@ -5814,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", @@ -5833,9 +6236,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.4" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", "windows-sys 0.61.2", @@ -5844,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]] @@ -5872,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.0", + "bitflags 2.11.0", ] [[package]] @@ -5921,9 +6329,15 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.118", + "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" @@ -5942,11 +6356,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.9" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0811b01ca2c4e8718760713911feaf4675c24f94e50530a015ec646cfb622f7c" +checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64" dependencies = [ - "skrifa 0.42.1", + "skrifa", "yazi", "zeno", ] @@ -5954,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.118" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -5988,7 +6392,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -6000,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" @@ -6012,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" @@ -6025,7 +6448,7 @@ 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.4", "windows-sys 0.61.2", @@ -6066,7 +6489,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -6077,7 +6500,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -6091,11 +6514,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.53" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde_core", @@ -6105,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.31" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -6122,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", ] @@ -6152,6 +6577,19 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny-xlib" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" +dependencies = [ + "as-raw-xcb-connection", + "ctor-lite", + "libloading", + "pkg-config", + "tracing", +] + [[package]] name = "tinystr" version = "0.8.3" @@ -6186,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", @@ -6210,32 +6648,18 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", ] [[package]] @@ -6247,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" @@ -6258,14 +6697,14 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap 2.14.0", "toml_datetime", "toml_parser", - "winnow", + "winnow 1.0.1", ] [[package]] @@ -6274,9 +6713,15 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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" @@ -6297,7 +6742,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -6354,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]] @@ -6365,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" @@ -6470,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" @@ -6486,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", @@ -6556,14 +7007,13 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.4" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom 0.4.3", + "getrandom 0.4.2", "js-sys", "serde_core", - "sha1_smol", "wasm-bindgen", ] @@ -6573,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" @@ -6597,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.126" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -6619,9 +7084,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.76" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ "js-sys", "wasm-bindgen", @@ -6629,9 +7094,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6639,26 +7104,60 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +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" @@ -6693,7 +7192,7 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "rustix 1.1.4", "wayland-backend", "wayland-scanner", @@ -6705,7 +7204,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "cursor-icon", "wayland-backend", ] @@ -6723,11 +7222,11 @@ dependencies = [ [[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.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -6740,7 +7239,7 @@ version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6753,7 +7252,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6766,7 +7265,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6779,7 +7278,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -6794,7 +7293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", - "quick-xml", + "quick-xml 0.39.2", "quote", ] @@ -6804,7 +7303,7 @@ version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "downcast-rs", "rustix 1.1.4", "wayland-backend", @@ -6825,9 +7324,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.103" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -6851,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.0", - "bytemuck", + "bitflags 2.11.0", "cfg-if", "cfg_aliases", "document-features", @@ -6881,14 +7379,14 @@ 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.0", + "bitflags 2.11.0", "bytemuck", "cfg_aliases", "document-features", @@ -6913,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.0", + "bitflags 2.11.0", "block", "bytemuck", "cfg-if", @@ -6956,6 +7454,7 @@ dependencies = [ "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", + "gpu-alloc", "gpu-allocator", "gpu-descriptor", "hashbrown 0.16.1", @@ -6982,20 +7481,21 @@ dependencies = [ "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.0", + "bitflags 2.11.0", "bytemuck", "js-sys", "log", + "thiserror 2.0.18", "web-sys", ] @@ -7033,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", @@ -7045,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]] @@ -7078,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]] @@ -7092,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", @@ -7105,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", @@ -7120,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]] @@ -7142,7 +7646,18 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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]] @@ -7153,7 +7668,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", ] [[package]] @@ -7179,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]] @@ -7206,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" @@ -7326,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" @@ -7476,8 +7991,9 @@ 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.0", + "bitflags 2.11.0", "cfg_aliases", "cursor-icon", "dpi", @@ -7495,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.0", + "bitflags 2.11.0", "dpi", "ndk", "raw-window-handle", @@ -7514,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.0", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "dpi", @@ -7535,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.0", + "bitflags 2.11.0", "cursor-icon", "dpi", "keyboard-types", @@ -7561,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.0", + "bitflags 2.11.0", "dpi", "libredox", "orbclient", "raw-window-handle", - "redox_event", + "redox_syscall 0.7.4", "smol_str", "tracing", "winit-core", @@ -7576,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.0", + "bitflags 2.11.0", "block2 0.6.2", "dispatch2", "dpi", @@ -7595,14 +8119,15 @@ 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.0", + "bitflags 2.11.0", "calloop", "cursor-icon", "dpi", "libc", - "memmap2 0.9.11", + "memmap2 0.9.10", "raw-window-handle", "rustix 1.1.4", "sctk-adwaita", @@ -7620,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.0", + "bitflags 2.11.0", "concurrent-queue", "cursor-icon", "dpi", @@ -7641,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.0", + "bitflags 2.11.0", "cursor-icon", "dpi", "raw-window-handle", @@ -7653,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.3" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +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" @@ -7683,6 +8324,39 @@ dependencies = [ "either", ] +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" @@ -7697,7 +8371,8 @@ checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xdg-shell-wrapper-config" -version = "1.3.0" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel#d518c7d25ef96f1a9696aa8cce008656bf66ece4" dependencies = [ "serde", "wayland-protocols-wlr", @@ -7743,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", ] @@ -7754,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", ] @@ -7764,7 +8439,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.11.0", "dlib", "log", "once_cell", @@ -7782,9 +8457,9 @@ dependencies = [ [[package]] name = "xml" -version = "1.3.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636f85e5ca6488e96401b61eb7de54f4e44755c988af0f52cf90230c312a1a89" +checksum = "b8aa498d22c9bbaf482329839bc5620c46be275a19a812e9a22a2b07529a642a" [[package]] name = "xml-rs" @@ -7821,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", @@ -7838,15 +8513,15 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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", @@ -7872,7 +8547,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", + "winnow 0.7.15", "zbus_macros", "zbus_names", "zvariant", @@ -7896,7 +8571,7 @@ checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn", "zbus-lockstep", "zbus_xml", "zvariant", @@ -7904,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.5", + "syn", "zbus_names", "zvariant", "zvariant_utils", @@ -7919,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.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ab0513c0a66a60a8718d5ad712a5094845a20d95b5c1c81e2bd8e904a52b4f" +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" @@ -7957,29 +8623,29 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.54" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.54" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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", ] @@ -7992,15 +8658,15 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "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" @@ -8034,74 +8700,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", -] - -[[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.4", - "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.118", -] - -[[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]] @@ -8142,50 +8741,41 @@ dependencies = [ [[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.5", + "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.5", - "winnow", + "syn", + "winnow 0.7.15", ] - -[[patch.unused]] -name = "winit-x11" -version = "0.31.0-beta.2" - -[[patch.unused]] -name = "cosmic-settings-airplane-mode-subscription" -version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index 0e75c5bc..5e6940de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,11 +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-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" @@ -38,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", @@ -48,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" @@ -59,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"] @@ -75,52 +74,20 @@ 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" } +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" } diff --git a/cosmic-app-list/Cargo.toml b/cosmic-app-list/Cargo.toml index 4616aa97..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.3.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 badf15ab..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.3.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/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 9129b9b4..e69de29b 100644 --- a/cosmic-app-list/i18n/oc/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/oc/cosmic_app_list.ftl @@ -1 +0,0 @@ -cosmic-app-list = Cinta d’aplicacions 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 77a0acb0..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), @@ -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); } @@ -2364,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( @@ -2379,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 @@ -2389,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(); @@ -2443,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() { @@ -2486,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( @@ -2502,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 @@ -2512,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(); @@ -2703,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() { @@ -2797,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() { @@ -2828,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), ) @@ -2840,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 = @@ -3006,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 @@ -3118,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 @@ -3180,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 dd93f90e..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.3.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 652f3b24..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), @@ -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) => { 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 8293cf56..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.3.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/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 82d7d6c4..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) => { @@ -550,12 +461,6 @@ impl cosmic::Application for Audio { cosmic::app::Action::Surface(a), )); } - Message::Client(client) => { - if let Some(client) = Arc::into_inner(client) { - self.audio_client = Some(client); - self.model = model::Model::default(); - } - } } Task::none() @@ -571,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)), ]) } @@ -625,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> { @@ -720,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)) @@ -742,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)) @@ -761,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) ] @@ -780,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) ] @@ -795,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, ), @@ -806,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, ) @@ -862,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) { @@ -921,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]), @@ -953,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 42c76b3c..00000000 --- a/cosmic-applet-audio/src/model.rs +++ /dev/null @@ -1,393 +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(); - if self.active == Some(pos) { - self.active = None; - } - 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 647ad9a1..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.3.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 13f245e7..33c18ba3 100644 --- a/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/zh-TW/cosmic_applet_battery.ftl @@ -1,4 +1,4 @@ -battery = 電池 +battery = 省電 battery-desc = 降低效能與耗電量。 balanced = 平衡 balanced-desc = 標準效能與耗電量。 @@ -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 a8936c42..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), @@ -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| { @@ -534,7 +507,7 @@ impl cosmic::Application for CosmicBatteryApplet { 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, @@ -544,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 d3499343..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.3.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/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/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/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 816c73c3..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), @@ -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, } => { @@ -373,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 c8c49af5..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.3.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 3109c888..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)] @@ -100,13 +96,12 @@ pub enum Message { KeyboardSettings, 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,10 +172,31 @@ 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}"); } } } @@ -202,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 { @@ -254,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))); @@ -281,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") @@ -295,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 { @@ -319,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 2ed9a552..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.3.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 089cc67e..e40a7551 100644 --- a/cosmic-applet-minimize/src/lib.rs +++ b/cosmic-applet-minimize/src/lib.rs @@ -248,48 +248,40 @@ 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!(), @@ -324,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 @@ -428,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 f9132d92..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.3.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/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/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/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 913712ca..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), 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,23 +981,19 @@ 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::Cosmic( @@ -1299,75 +1001,59 @@ impl cosmic::Application for CosmicNetworkApplet { )); } 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, @@ -1375,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:?}") @@ -1424,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, .. }) = @@ -1463,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() { @@ -1563,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 }) @@ -1599,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() @@ -1631,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) @@ -1652,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) @@ -1676,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()]; @@ -1720,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) @@ -1744,8 +1510,7 @@ impl cosmic::Application for CosmicNetworkApplet { } ActiveConnectionInfo::WiFi { name, - ip4_address, - ip6_address, + ip_addresses, state, strength, hw_address, @@ -1755,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) @@ -1763,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")) @@ -1788,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(), ); @@ -1803,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), @@ -1916,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() { @@ -1960,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); @@ -1981,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") @@ -2006,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(), ); @@ -2018,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 @@ -2027,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( @@ -2094,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); @@ -2152,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), ); @@ -2207,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 @@ -2274,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 0d52f0e0..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.3.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 720f8d63..438696b9 100644 --- a/cosmic-applet-notifications/src/lib.rs +++ b/cosmic-applet-notifications/src/lib.rs @@ -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) => { diff --git a/cosmic-applet-power/Cargo.toml b/cosmic-applet-power/Cargo.toml index 14c027a2..041c0474 100644 --- a/cosmic-applet-power/Cargo.toml +++ b/cosmic-applet-power/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "cosmic-applet-power" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] i18n-embed-fl.workspace = true i18n-embed.workspace = true -cosmic.workspace = true +libcosmic.workspace = true logind-zbus = "5.3.2" rust-embed.workspace = true rustix.workspace = true diff --git a/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl index 8fcd19ec..e69de29b 100644 --- a/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl @@ -1,36 +0,0 @@ -cancel = Cancel·lar -confirm = Confirmar -restart = Reinicia -suspend = Suspèn -confirm-button = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] Apaga - [log-out] { log-out } - *[other] { confirm } - } -power = Energia -confirm-body = - { $action -> - [restart] L'ordinador es reiniciarà - [suspend] L'ordinador se suspendrà - [shutdown] L'ordinador s'apagarà - [lock-screen] La pantalla es bloquejarà - [log-out] La sessió es tancarà - *[other] L'acció seleccionada es durà a terme - } automàticament d'aquí a { $countdown } segons. -lock-screen = Bloqueja la pantalla -shutdown = Apaga -log-out = Tanca la sessió -log-out-shortcut = Súper + Majús + Esc -settings = Configuració... -lock-screen-shortcut = Súper + Esc -confirm-title = - ¿{ $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] { shutdown } - [log-out] Voleu tancar totes les aplicacions i tancar la sessió - *[other] Voleu dur a terme l'acció seleccionada - }? diff --git a/cosmic-applet-power/i18n/da/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/da/cosmic_applet_power.ftl index 0af42d3a..e69de29b 100644 --- a/cosmic-applet-power/i18n/da/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/da/cosmic_applet_power.ftl @@ -1,28 +0,0 @@ -power = Strøm -confirm-body = - Systemet vil automatisk { $action -> - [restart] genstarte - [suspend] slumre - [shutdown] slukke - [lock-screen] låse skærmen - [log-out] logge ud - *[other] anvende den valgte handling - } om { $countdown } sekunder. -lock-screen = Låseskærm -shutdown = Nedlukning -log-out = Log Ud -restart = Genstart -log-out-shortcut = Super + Skift + Escape -cancel = Afbryd -suspend = Slumre -confirm = Bekræft -settings = Indstillinger... -lock-screen-shortcut = Super + Escape -confirm-title = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] { shutdown } - [log-out] Forlad alle applikationer og log ud - *[other] Anvend den valgte handling - } nu? diff --git a/cosmic-applet-power/i18n/de/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/de/cosmic_applet_power.ftl index f630d8e4..652e2f9b 100644 --- a/cosmic-applet-power/i18n/de/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/de/cosmic_applet_power.ftl @@ -1,5 +1,5 @@ power = Energie -settings = Einstellungen ... +settings = Einstellungen... lock-screen = Sperrbildschirm lock-screen-shortcut = Super + Esc log-out = Abmelden diff --git a/cosmic-applet-power/i18n/el/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/el/cosmic_applet_power.ftl index bc5a945c..41e6b281 100644 --- a/cosmic-applet-power/i18n/el/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/el/cosmic_applet_power.ftl @@ -4,33 +4,3 @@ log-out = Αποσύνδεση restart = Επανεκκίνηση suspend = Αναστολή confirm = Επιβεβαίωση -confirm-button = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] Τερματισμός - [log-out] { log-out } - *[other] { confirm } - } -power = Ενέργεια -confirm-body = - Θα εκτελεστεί αυτόματα { $action -> - [restart] επανεκκίνηση - [suspend] αναστολή - [shutdown] τερματισμός - [lock-screen] κλείδωμα της οθόνης - [log-out] αποσύνδεση - *[other] η επιλεγμένη ενέργεια - } του συστήματος σε { $countdown } δευτερόλεπτα. -lock-screen = Κλείδωμα οθόνης -log-out-shortcut = Super + Shift + Escape -settings = Ρυθμίσεις... -lock-screen-shortcut = Super + Escape -confirm-title = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] { shutdown } - [log-out] Έξοδος από όλες τις εφαρμογές και αποσύνδεση - *[other] Εφαρμογή της επιλεγμένης ενέργειας - } τώρα; diff --git a/cosmic-applet-power/i18n/fil/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/fil/cosmic_applet_power.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-power/i18n/gl/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/gl/cosmic_applet_power.ftl deleted file mode 100644 index 50aff75b..00000000 --- a/cosmic-applet-power/i18n/gl/cosmic_applet_power.ftl +++ /dev/null @@ -1,36 +0,0 @@ -power = Enerxía -settings = Axustes... -lock-screen = Pantalla de Bloqueo -lock-screen-shortcut = Super + Esc -log-out = Pechar Sesión -log-out-shortcut = Super + Maiús + Esc -suspend = Suspender -restart = Reiniciar -shutdown = Apagar -confirm = Confirmar -cancel = Cancelar -confirm-button = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] Apagar - [log-out] { log-out } - *[other] { confirm } - } -confirm-title = - { $action -> - [restart] { restart } agora? - [suspend] { suspend } agora? - [shutdown] { shutdown } agora? - [log-out] Pechar todas as aplicacións e pechar a sesión agora? - *[other] Aplicar a acción seleccionada agora - } -confirm-body = - O sistema { $action -> - [restart] reiniciarase - [suspend] suspenderase - [shutdown] apagarase - [lock-screen] bloqueará a pantalla - [log-out] pechará a sesión - *[other] aplicará a acción seleccionada - } automaticamente en { $countdown } segundos. diff --git a/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl index 9791f43f..9019650a 100644 --- a/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl @@ -33,4 +33,4 @@ confirm-body = [lock-screen] zárolni fogja a képernyőt [log-out] kijelentkezik *[other] alkalmazni fogja a kiválasztott műveletet - } { $countdown } másodperc múlva. + } { $countdown } másodperc múlva diff --git a/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl index 003f4a23..e69de29b 100644 --- a/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl @@ -1,36 +0,0 @@ -cancel = Têk bibe -confirm = Bipejirîne -power = Hêz -restart = Ji nû ve bide destpêkirin -settings = Sazkarî... -shutdown = Vemrîne -suspend = Rawestîne -log-out = Derkeve -lock-screen = Dîmenderê kilît bike -lock-screen-shortcut = Super + Escape -log-out-shortcut = Super + Shift + Escape -confirm-button = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] Vemrîne - [log-out] { log-out } - *[other] { confirm } - } -confirm-title = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] { shutdown } - [log-out] Hemû sepanan bigire û derkeve - *[other] Çalakiyê hilbijartî bisepîne - } niha? -confirm-body = - Pergal wê xweber were { $action -> - [restart] jinûvedestpêkkirin - [suspend] rawestandin - [shutdown] vemirandin - [lock-screen] kilîtkirin - [log-out] derketin - *[other] çalakiyê hilbijartî bisepîne - }di { $countdown } çirke de. diff --git a/cosmic-applet-power/i18n/lo/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/lo/cosmic_applet_power.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-power/i18n/sat/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/sat/cosmic_applet_power.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-power/i18n/sr/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/sr/cosmic_applet_power.ftl index 800b2900..e69de29b 100644 --- a/cosmic-applet-power/i18n/sr/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/sr/cosmic_applet_power.ftl @@ -1,36 +0,0 @@ -power = Напајање -lock-screen = Закључај екран -shutdown = Угаси -log-out = Одјава -restart = Поново покрени -log-out-shortcut = Супер + Shift + Esc -cancel = Откажи -suspend = Обустави -confirm = Потврди -settings = Подешавања... -lock-screen-shortcut = Супер + Esc -confirm-button = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] Искључи - [log-out] { log-out } - *[other] { confirm } - } -confirm-body = - Систем ће { $action -> - [restart] поново покренути - [suspend] обуставити - [shutdown] искључити - [lock-screen] закључати екран - [log-out] одјавити се - *[other] применити изабрану радњу - } самостално за { $countdown } секунде. -confirm-title = - { $action -> - [restart] { restart } - [suspend] { suspend } - [shutdown] { shutdown } - [log-out] Затвори све програме и одјави се - *[other] Примени изабрану радњу - } сада? diff --git a/cosmic-applet-power/src/lib.rs b/cosmic-applet-power/src/lib.rs index aa07ff3b..67725fbc 100644 --- a/cosmic-applet-power/src/lib.rs +++ b/cosmic-applet-power/src/lib.rs @@ -16,8 +16,9 @@ use cosmic::{ window, }, surface, theme, - widget::{button, divider, icon, space, text}, + widget::{Space, button, divider, icon, space, text}, }; +use std::sync::LazyLock; use logind_zbus::{ manager::ManagerProxy, @@ -34,6 +35,9 @@ pub mod session_manager; use crate::{cosmic_session::CosmicSessionProxy, session_manager::SessionManagerProxy}; +static SUBSURFACE_ID: LazyLock = + LazyLock::new(|| cosmic::widget::Id::new("subsurface")); + pub fn run() -> cosmic::iced::Result { localize::localize(); @@ -45,6 +49,7 @@ struct Power { icon_name: String, popup: Option, token_tx: Option>, + subsurface_id: window::Id, } #[derive(Debug, Clone, Copy)] @@ -70,7 +75,6 @@ impl PowerAction { } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { Action(PowerAction), TogglePopup, @@ -100,6 +104,7 @@ impl cosmic::Application for Power { Self { core, icon_name: "system-shutdown-symbolic".to_string(), + subsurface_id: window::Id::unique(), token_tx: None, popup: Option::default(), }, @@ -115,27 +120,20 @@ impl cosmic::Application for Power { match message { 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 Power| { - 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::OpenSettings => { diff --git a/cosmic-applet-status-area/Cargo.toml b/cosmic-applet-status-area/Cargo.toml index d939230c..fe85ad48 100644 --- a/cosmic-applet-status-area/Cargo.toml +++ b/cosmic-applet-status-area/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "cosmic-applet-status-area" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] futures.workspace = true -cosmic.workspace = true +libcosmic.workspace = true serde.workspace = true rustc-hash.workspace = true tokio.workspace = true diff --git a/cosmic-applet-status-area/src/components/app.rs b/cosmic-applet-status-area/src/components/app.rs index d98cc117..1071d7ac 100644 --- a/cosmic-applet-status-area/src/components/app.rs +++ b/cosmic-applet-status-area/src/components/app.rs @@ -9,14 +9,11 @@ use cosmic::{ }, cctk::sctk::reexports::calloop, iced::{ - self, - Event::Mouse, - Length, Subscription, event, - mouse::{self, ScrollDelta}, + self, Length, Subscription, platform_specific::shell::commands::popup::{destroy_popup, get_popup}, + theme::Style, window, }, - scroll::{DiscreteScrollDelta, DiscreteScrollState}, surface, widget::{container, mouse_area}, }; @@ -28,7 +25,6 @@ use crate::{ }; #[derive(Clone, Debug)] -#[allow(dead_code)] pub enum Msg { None, Activate(usize), @@ -37,8 +33,7 @@ pub enum Msg { StatusMenu((usize, status_menu::Msg)), StatusNotifier(status_notifier_watcher::Event), TogglePopup(usize), - Hovered(Option), - WheelScrolled(ScrollDelta), + Hovered(usize), Surface(surface::Action), ToggleOverflow, HoveredOverflow, @@ -54,8 +49,6 @@ pub(crate) struct App { max_menu_id: usize, popup: Option, overflow_popup: Option, - hovered_menu: Option, - scroll_states: BTreeMap, token_tx: Option>, } @@ -110,10 +103,9 @@ impl App { let overflow_index = self.overflow_index().unwrap_or(0); let children = self.menus.iter().skip(overflow_index).map(|(id, menu)| { mouse_area( - menu_icon_button(&self.core.applet, menu).on_press_down(Msg::TogglePopup(*id)), + menu_icon_button(&self.core.applet, &menu).on_press_down(Msg::TogglePopup(*id)), ) - .on_enter(Msg::Hovered(Some(*id))) - .on_exit(Msg::Hovered(None)) + .on_enter(Msg::Hovered(*id)) .into() }); @@ -218,7 +210,6 @@ impl cosmic::Application for App { { let id = *id; self.menus.remove(&id); - self.scroll_states.remove(&id); if self.open_menu == Some(id) { self.open_menu = None; if let Some(popup_id) = self.popup { @@ -246,49 +237,38 @@ impl cosmic::Application for App { if let Some(popup_id) = self.popup.take() { cmds.push(destroy_popup(popup_id)); } + let popup_id = self.next_popup_id(); + let i = self.menus.keys().position(|&i| i == id).unwrap(); + let (i, parent) = self + .overflow_index() + .and_then(|overflow_i| { + if overflow_i <= i { + Some(i - overflow_i).zip(self.overflow_popup) + } else { + Some((i, self.core.main_window_id().unwrap())) + } + }) + .unwrap_or((i, self.core.main_window_id().unwrap())); - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let popup_id = app.next_popup_id(); - let i = app.menus.keys().position(|&i| i == id).unwrap(); - let (i, parent) = app - .overflow_index() - .and_then(|overflow_i| { - if overflow_i <= i { - Some(i - overflow_i).zip(app.overflow_popup) - } else { - Some((i, app.core.main_window_id().unwrap())) - } - }) - .unwrap_or((i, app.core.main_window_id().unwrap())); + let mut popup_settings = self + .core + .applet + .get_popup_settings(parent, popup_id, None, None, None); + self.popup = Some(popup_id); - let mut popup_settings = app - .core - .applet - .get_popup_settings(parent, popup_id, None, None, None); - app.popup = Some(popup_id); - - if matches!( - app.core.applet.anchor, - PanelAnchor::Left | PanelAnchor::Right - ) { - let suggested_size = app.core.applet.suggested_size(false).1 - + 2 * app.core.applet.suggested_padding(false).1; - popup_settings.positioner.anchor_rect.y = - i as i32 * suggested_size as i32; - } else { - let suggested_size = app.core.applet.suggested_size(false).0 - + 2 * app.core.applet.suggested_padding(false).1; - popup_settings.positioner.anchor_rect.x = - i as i32 * suggested_size as i32; - } - popup_settings - }, - None, - )); - cmds.push(popup_task); + if matches!( + self.core.applet.anchor, + PanelAnchor::Left | PanelAnchor::Right + ) { + let suggested_size = self.core.applet.suggested_size(false).1 + + 2 * self.core.applet.suggested_padding(false).1; + popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; + } else { + let suggested_size = self.core.applet.suggested_size(false).0 + + 2 * self.core.applet.suggested_padding(false).1; + popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; + } + cmds.push(get_popup(popup_settings)); return app::Task::batch(cmds); } else if let Some(popup_id) = self.popup { self.menus[&id].closed(); @@ -332,10 +312,6 @@ impl cosmic::Application for App { } }, Msg::Hovered(id) => { - self.hovered_menu = id; - let Some(id) = id else { - return Task::none(); - }; let mut cmds = Vec::new(); if let Some(old_id) = self.open_menu.take() { if old_id != id { @@ -350,64 +326,41 @@ impl cosmic::Application for App { } else { return Task::none(); } - let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let popup_id = app.next_popup_id(); - let i = app.menus.keys().position(|&i| i == id).unwrap(); + let popup_id = self.next_popup_id(); + let i = self.menus.keys().position(|&i| i == id).unwrap(); - let (i, parent) = app - .overflow_index() - .and_then(|overflow_i| { - if overflow_i <= i { - Some(i - overflow_i).zip(app.overflow_popup) - } else { - Some((i, app.core.main_window_id().unwrap())) - } - }) - .unwrap_or((i, app.core.main_window_id().unwrap())); - - let mut popup_settings = app - .core - .applet - .get_popup_settings(parent, popup_id, None, None, None); - app.popup = Some(popup_id); - - if matches!( - app.core.applet.anchor, - PanelAnchor::Left | PanelAnchor::Right - ) { - let suggested_size = app.core.applet.suggested_size(true).1 - + 2 * app.core.applet.suggested_padding(true).1; - popup_settings.positioner.anchor_rect.y = - i as i32 * suggested_size as i32; + let (i, parent) = self + .overflow_index() + .and_then(|overflow_i| { + if overflow_i <= i { + Some(i - overflow_i).zip(self.overflow_popup) } else { - let suggested_size = app.core.applet.suggested_size(true).0 - + 2 * app.core.applet.suggested_padding(true).0; - popup_settings.positioner.anchor_rect.x = - i as i32 * suggested_size as i32; + Some((i, self.core.main_window_id().unwrap())) } - popup_settings - }, - None, - )); - cmds.push(popup_task); + }) + .unwrap_or((i, self.core.main_window_id().unwrap())); + let mut popup_settings = self + .core + .applet + .get_popup_settings(parent, popup_id, None, None, None); + self.popup = Some(popup_id); + + if matches!( + self.core.applet.anchor, + PanelAnchor::Left | PanelAnchor::Right + ) { + let suggested_size = self.core.applet.suggested_size(true).1 + + 2 * self.core.applet.suggested_padding(true).1; + popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; + } else { + let suggested_size = self.core.applet.suggested_size(true).0 + + 2 * self.core.applet.suggested_padding(true).0; + popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; + } + cmds.push(get_popup(popup_settings)); Task::batch(cmds) } - Msg::WheelScrolled(delta) => { - let Some(id) = self.hovered_menu else { - return Task::none(); - }; - let discrete_delta = self.scroll_states.entry(id).or_default().update(delta); - let Some((delta, orientation)) = discrete_scroll_delta(discrete_delta) else { - return Task::none(); - }; - let Some(menu) = self.menus.get(&id) else { - return Task::none(); - }; - scroll(id, menu.item.item_proxy().clone(), delta, orientation) - } Msg::Surface(a) => { return cosmic::task::message(cosmic::Action::Cosmic( cosmic::app::Action::Surface(a), @@ -420,47 +373,38 @@ impl cosmic::Application for App { return destroy_popup(popup_id); } else if let Some(overflow_index) = self.overflow_index() { // If we don't have an overflow, create it - let popup_task = - cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let popup_id = app.next_popup_id(); - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - popup_id, - None, - None, - None, - ); - popup_settings.close_with_children = false; + let popup_id = self.next_popup_id(); + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + popup_id, + None, + None, + None, + ); + popup_settings.close_with_children = false; - if matches!( - app.core.applet.anchor, - PanelAnchor::Left | PanelAnchor::Right - ) { - let suggested_size = app.core.applet.suggested_size(true).1 - + 2 * app.core.applet.suggested_padding(true).1; - popup_settings.positioner.anchor_rect.y = - overflow_index as i32 * suggested_size as i32; - } else { - let suggested_size = app.core.applet.suggested_size(true).0 - + 2 * app.core.applet.suggested_padding(true).0; - popup_settings.positioner.anchor_rect.x = - overflow_index as i32 * suggested_size as i32; - } + if matches!( + self.core.applet.anchor, + PanelAnchor::Left | PanelAnchor::Right + ) { + let suggested_size = self.core.applet.suggested_size(true).1 + + 2 * self.core.applet.suggested_padding(true).1; + popup_settings.positioner.anchor_rect.y = + overflow_index as i32 * suggested_size as i32; + } else { + let suggested_size = self.core.applet.suggested_size(true).0 + + 2 * self.core.applet.suggested_padding(true).0; + popup_settings.positioner.anchor_rect.x = + overflow_index as i32 * suggested_size as i32; + } - app.overflow_popup = Some(popup_id); - popup_settings - }, - None, - )); - return popup_task; + self.overflow_popup = Some(popup_id); + return get_popup(popup_settings); } else { return Task::none(); } } Msg::HoveredOverflow => { - self.hovered_menu = None; let mut cmds = Vec::new(); if self.overflow_popup.is_some() { // If we already have an overflow popup, do nothing @@ -473,41 +417,34 @@ impl cosmic::Application for App { } else { return Task::none(); } + + let popup_id = self.next_popup_id(); + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + popup_id, + None, + None, + None, + ); + self.popup = Some(popup_id); + let Some(i) = self.overflow_index() else { return Task::batch(cmds); }; - let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - move |app: &mut Self| { - let popup_id = app.next_popup_id(); - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - popup_id, - None, - None, - None, - ); - app.popup = Some(popup_id); - if matches!( - app.core.applet.anchor, - PanelAnchor::Left | PanelAnchor::Right - ) { - let suggested_size = app.core.applet.suggested_size(false).1 - + 2 * app.core.applet.suggested_padding(false).1; - popup_settings.positioner.anchor_rect.y = - i as i32 * suggested_size as i32; - } else { - let suggested_size = app.core.applet.suggested_size(false).0 - + 2 * app.core.applet.suggested_padding(false).1; - popup_settings.positioner.anchor_rect.x = - i as i32 * suggested_size as i32; - } - popup_settings - }, - None, - )); - cmds.push(popup_task); + if matches!( + self.core.applet.anchor, + PanelAnchor::Left | PanelAnchor::Right + ) { + let suggested_size = self.core.applet.suggested_size(false).1 + + 2 * self.core.applet.suggested_padding(false).1; + popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; + } else { + let suggested_size = self.core.applet.suggested_size(false).0 + + 2 * self.core.applet.suggested_padding(false).1; + popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; + } + cmds.push(get_popup(popup_settings)); Task::batch(cmds) } } @@ -523,12 +460,6 @@ impl cosmic::Application for App { subscriptions.push(menu.subscription(is_open).with(*id).map(Msg::StatusMenu)); } subscriptions.push(activation_token_subscription(0).map(Msg::Token)); - subscriptions.push(event::listen_with(|e, status, _| match (e, status) { - (Mouse(mouse::Event::WheelScrolled { delta }), event::Status::Ignored) => { - Some(Msg::WheelScrolled(delta)) - } - _ => None, - })); iced::Subscription::batch(subscriptions) } @@ -541,10 +472,9 @@ impl cosmic::Application for App { .iter() .take(overflow_index.unwrap_or(self.menus.len())) .map(|(id, menu)| { - mouse_area(menu_icon_button(&self.core.applet, menu).on_press(Msg::Activate(*id))) + mouse_area(menu_icon_button(&self.core.applet, &menu).on_press(Msg::Activate(*id))) .on_right_press(Msg::TogglePopup(*id)) - .on_enter(Msg::Hovered(Some(*id))) - .on_exit(Msg::Hovered(None)) + .on_enter(Msg::Hovered(*id)) .into() }); @@ -640,33 +570,6 @@ fn activate( }) } -fn scroll( - id: usize, - item_proxy: crate::subscriptions::status_notifier_item::StatusNotifierItemProxy<'static>, - delta: i32, - orientation: &'static str, -) -> Task> { - Task::future(async move { - match item_proxy.scroll(delta, orientation).await { - Ok(_) => cosmic::action::app(Msg::None), - Err(err) => { - tracing::error!("Scroll failed for {}: {}", id, err); - cosmic::action::app(Msg::None) - } - } - }) -} - -fn discrete_scroll_delta(delta: DiscreteScrollDelta) -> Option<(i32, &'static str)> { - if delta.y != 0 { - Some((delta.y as i32, "vertical")) - } else if delta.x != 0 { - Some((delta.x as i32, "horizontal")) - } else { - None - } -} - fn menu_icon_button<'a>( applet: &'a cosmic::applet::Context, menu: &'a status_menu::State, @@ -674,7 +577,7 @@ fn menu_icon_button<'a>( let icon = menu.icon_handle().clone(); let theme = cosmic::theme::active(); - let _theme = theme.cosmic(); + let theme = theme.cosmic(); let suggested = applet.suggested_size(true); let padding = applet.suggested_padding(true).1; @@ -692,7 +595,7 @@ fn menu_icon_button<'a>( .class(if symbolic { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::iced::widget::svg::Style { - color: Some(theme.cosmic().background(theme.transparent).on.into()), + color: Some(theme.cosmic().background.on.into()), } })) } else { @@ -711,43 +614,3 @@ fn menu_icon_button<'a>( pub fn main() -> iced::Result { cosmic::applet::run::(()) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn discrete_scroll_prefers_vertical_delta() { - assert_eq!( - discrete_scroll_delta(cosmic::scroll::DiscreteScrollDelta { x: 4, y: -2 }), - Some((-2, "vertical")) - ); - } - - #[test] - fn discrete_scroll_uses_horizontal_delta_when_vertical_is_zero() { - assert_eq!( - discrete_scroll_delta(cosmic::scroll::DiscreteScrollDelta { x: 3, y: 0 }), - Some((3, "horizontal")) - ); - } - - #[test] - fn discrete_scroll_ignores_zero_delta() { - assert_eq!( - discrete_scroll_delta(cosmic::scroll::DiscreteScrollDelta { x: 0, y: 0 }), - None - ); - } - - #[test] - fn pixel_scroll_accumulates_before_emitting_discrete_delta() { - let mut state = cosmic::scroll::DiscreteScrollState::default(); - - let first = state.update(ScrollDelta::Pixels { x: 0.0, y: 12.0 }); - assert_eq!(discrete_scroll_delta(first), None); - - let second = state.update(ScrollDelta::Pixels { x: 0.0, y: 12.0 }); - assert_eq!(discrete_scroll_delta(second), Some((1, "vertical"))); - } -} diff --git a/cosmic-applet-status-area/src/components/status_menu.rs b/cosmic-applet-status-area/src/components/status_menu.rs index a228d745..fedd79e4 100644 --- a/cosmic-applet-status-area/src/components/status_menu.rs +++ b/cosmic-applet-status-area/src/components/status_menu.rs @@ -26,7 +26,6 @@ pub struct State { expanded: Option, // TODO handle icon with multiple sizes? icon_handle: icon::Handle, - icon_theme_path: Option, click_event: Option<(i32, bool)>, } @@ -40,7 +39,6 @@ impl State { icon_handle: icon::from_name("application-default") .prefer_svg(true) .handle(), - icon_theme_path: None, click_event: None, }, iced::Task::none(), @@ -65,7 +63,6 @@ impl State { } Msg::Icon(update) => { let icon_name = update.name.unwrap_or_default(); - self.icon_theme_path = update.theme_path; // Use the icon pixmap if an icon was not defined by name. if icon_name.is_empty() { @@ -96,18 +93,13 @@ impl State { self.icon_handle = if Path::new(&icon_name).exists() { icon::from_path(Path::new(&icon_name).to_path_buf()).symbolic(true) } else { - let mut builder = icon::from_name(icon_name).prefer_svg(true).fallback(Some( - IconFallback::Names(vec![ + icon::from_name(icon_name) + .prefer_svg(true) + .fallback(Some(IconFallback::Names(vec![ "application-default".into(), "application-x-executable".into(), - ]), - )); - - if let Some(ref theme_path) = self.icon_theme_path { - builder = builder.with_extra_paths(vec![theme_path.clone()]); - } - - builder.handle() + ]))) + .handle() }; iced::Task::none() @@ -232,11 +224,7 @@ fn layout_view(layout: &Layout, expanded: Option) -> cosmic::Element<'_, Ms } if let Some(icon_data) = i.icon_data() { let handle = iced::widget::image::Handle::from_bytes(icon_data.to_vec()); - let icon = iced::widget::Image::new(handle) - .width(iced::Length::Fixed(14.0)) - .height(iced::Length::Fixed(14.0)) - .content_fit(iced::core::ContentFit::Contain); - children.insert(0, icon.into()); + children.insert(0, iced::widget::Image::new(handle).into()); } else if let Some(icon_name) = i.icon_name() { let icon = cosmic::widget::icon::from_name(icon_name) .size(14) diff --git a/cosmic-applet-status-area/src/status_notifier_watcher.rs b/cosmic-applet-status-area/src/status_notifier_watcher.rs index 5c8b6175..1bb75d79 100644 --- a/cosmic-applet-status-area/src/status_notifier_watcher.rs +++ b/cosmic-applet-status-area/src/status_notifier_watcher.rs @@ -10,18 +10,21 @@ //! can be socket-activated and not conflict with anything else running as a status notifier //! watcher. //! -//! The daemon runs as long as there is at least one client still connected. +//! The daemon runs as long as as there is at least one client still connected. Which it checks +//! for every `REFRESH_INTERVAL`. use crate::subscriptions::status_notifier_watcher::server::create_service; use crate::unique_names::UniqueNames; use futures::StreamExt; -use std::collections::HashSet; +use std::{collections::HashSet, time::Duration}; use zbus::fdo; use zbus::message::Header; const DBUS_NAME: &str = "com.system76.CosmicStatusNotifierWatcher"; const OBJECT_PATH: &str = "/CosmicStatusNotifierWatcher"; +const REFRESH_INTERVAL: Duration = Duration::from_secs(60); + /// Run daemon pub fn run() -> cosmic::iced::Result { if let Err(err) = run_inner() { @@ -39,7 +42,7 @@ pub async fn cosmic_register(conn: &zbus::Connection) -> zbus::Result<()> { tokio::spawn(async move { while let Some(value) = stream.next().await { if let Some(_unique_name) = value { - // Register with new owner. + /// Register with new owner let _ = cosmic_watcher.register_applet().await; } } diff --git a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs index 2c3d4904..fd51390e 100644 --- a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs +++ b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use std::hash::Hash; -use std::path::PathBuf; use cosmic::iced::{self, Subscription}; use futures::{FutureExt, StreamExt}; @@ -28,7 +27,7 @@ pub struct Icon { pub struct IconUpdate { pub name: Option, pub pixmap: Option>, - pub theme_path: Option, + // pub theme_path: Option, } impl StatusNotifierItem { @@ -119,11 +118,11 @@ impl StatusNotifierItem { async fn icon_events(item_proxy: StatusNotifierItemProxy<'static>) -> IconUpdate { let icon_name = item_proxy.icon_name().await; let icon_pixmap = item_proxy.icon_pixmap().await; - let icon_theme_path = item_proxy.icon_theme_path().await.map(PathBuf::from); + // let icon_theme_path = item_proxy.icon_theme_path().await.map(PathBuf::from); IconUpdate { name: icon_name.ok(), pixmap: icon_pixmap.ok(), - theme_path: icon_theme_path.ok().filter(|x| !x.as_os_str().is_empty()), + // theme_path: icon_theme_path.ok().filter(|x| !x.as_os_str().is_empty()), } } @@ -202,8 +201,6 @@ pub trait StatusNotifierItem { fn activate(&self, x: i32, y: i32) -> zbus::Result<()>; fn secondary_activate(&self, x: i32, y: i32) -> zbus::Result<()>; - - fn scroll(&self, delta: i32, orientation: &str) -> zbus::Result<()>; } #[derive(Clone, Debug)] diff --git a/cosmic-applet-tiling/Cargo.toml b/cosmic-applet-tiling/Cargo.toml index d0c08c1f..23e689e0 100644 --- a/cosmic-applet-tiling/Cargo.toml +++ b/cosmic-applet-tiling/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "cosmic-applet-tiling" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] -cosmic.workspace = true +libcosmic.workspace = true anyhow.workspace = true cctk.workspace = true -cosmic-comp-config.workspace = true +cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } cosmic-protocols.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true diff --git a/cosmic-applet-tiling/i18n/ca/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/ca/cosmic_applet_tiling.ftl index 4160088d..e69de29b 100644 --- a/cosmic-applet-tiling/i18n/ca/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/ca/cosmic_applet_tiling.ftl @@ -1,2 +0,0 @@ -tile-windows = Organitza les finestres en mosaic automàticament -shortcuts = Dreceres diff --git a/cosmic-applet-tiling/i18n/de/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/de/cosmic_applet_tiling.ftl index 4e367370..2f41f75e 100644 --- a/cosmic-applet-tiling/i18n/de/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/de/cosmic_applet_tiling.ftl @@ -4,11 +4,11 @@ shortcuts = Tastenkombinationen navigate-windows = Fenster navigieren move-window = Fenster verschieben toggle-floating-window = Schwebendes Fenster umschalten -view-all-shortcuts = Alle Tastenkombinationen ansehen ... +view-all-shortcuts = Alle Tastenkombinationen ansehen... active-hint = Aktiv-Hinweis gaps = Lücken -floating-window-exceptions = Ausnahmen für schwebende Fenster ... -window-management-settings = Einstellungen für die Fensterverwaltung ... +floating-window-exceptions = Ausnahmen für schwebende Fenster... +window-management-settings = Einstellungen für die Fensterverwaltung... all-workspaces = Alle Arbeitsflächen per-workspace = Pro Arbeitsfläche super = Super diff --git a/cosmic-applet-tiling/i18n/el/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/el/cosmic_applet_tiling.ftl index 9c9d7e68..e69de29b 100644 --- a/cosmic-applet-tiling/i18n/el/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/el/cosmic_applet_tiling.ftl @@ -1,20 +0,0 @@ -arrow-keys = βέλη -move-window = Μετακίνηση παραθύρου -shift = Shift -super = Super -new-workspace = Συμπεριφορά νέων χώρων εργασίας -tiled = Παράθεση -active-hint = Ένδειξη ενεργού παραθύρου -navigate-windows = Πλοήγηση στα παράθυρα -toggle-floating-window = Εναλλαγή αιώρησης παραθύρων -all-workspaces = Όλοι οι χώροι εργασίας -per-workspace = Ανά χώρο εργασίας -autotile-behavior = Παράθεση παραθύρων στους χώρους εργασίας -tile-current = Παράθεση στον τρέχοντα χώρο εργασίας -floating = Αιώρηση -gaps = Κενά -tile-windows = Αυτόματη παράθεση παραθύρων -view-all-shortcuts = Προβολή όλων των συντομεύσεων... -shortcuts = Συντομεύσεις -floating-window-exceptions = Εξαιρέσεις αιωρούμενων παραθύρων... -window-management-settings = Ρυθμίσεις διαχείρισης παραθύρων... diff --git a/cosmic-applet-tiling/i18n/fil/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/fil/cosmic_applet_tiling.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-tiling/i18n/gl/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/gl/cosmic_applet_tiling.ftl deleted file mode 100644 index 1bd9f731..00000000 --- a/cosmic-applet-tiling/i18n/gl/cosmic_applet_tiling.ftl +++ /dev/null @@ -1,20 +0,0 @@ -tile-windows = Dispoñer as xanelas en mosaico automaticamente -tile-current = Dispoñer en mosaico o espazo de traballo actual -shortcuts = Atallos -navigate-windows = Navergar polas xanelas -move-window = Mover a xanela -toggle-floating-window = Alternar xanela flotante -view-all-shortcuts = Ver todos os atallos... -active-hint = Indicador de foco activo -gaps = Espazos -floating-window-exceptions = Excepcións de xanelas flotantes... -window-management-settings = Axustes da xestión de xanelas... -all-workspaces = Todos os espazos de traballo -per-workspace = Por espazo de traballo -super = Super -shift = Maiús -arrow-keys = frechas -tiled = En mosaico -floating = Flotante -autotile-behavior = Organizar as xanelas en mosaico nos espazos de traballo -new-workspace = Comportamento dos novos espazos de traballo diff --git a/cosmic-applet-tiling/i18n/hu/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/hu/cosmic_applet_tiling.ftl index a2d0d4bc..7d622463 100644 --- a/cosmic-applet-tiling/i18n/hu/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/hu/cosmic_applet_tiling.ftl @@ -3,11 +3,11 @@ tile-current = Jelenlegi munkaterület csempézése shortcuts = Gyorsbillentyűk navigate-windows = Ablakok navigálása move-window = Ablak mozgatása -toggle-floating-window = Lebegő ablak be/ki +toggle-floating-window = Az ablakok lebegtetésének be- és kikapcsolása view-all-shortcuts = Az összes gyorsbillentyű megtekintése… active-hint = Aktív ablak kiemelése gaps = Hézagok -floating-window-exceptions = Lebegőablak-kivételek… +floating-window-exceptions = Lebegő ablak kivételek… window-management-settings = Ablakkezelési beállítások… all-workspaces = Összes munkaterület per-workspace = Munkaterületenként diff --git a/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl index e3f124ff..e69de29b 100644 --- a/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl @@ -1,20 +0,0 @@ -tile-windows = Çarçoveyan xweber berhev bike -tile-current = Qada xebatê heyî berhev bike -shortcuts = Kurterê -navigate-windows = Di nav çarçoveyan de bigere -move-window = Çarçoveyê bilivîne -toggle-floating-window = Rewşê çarçoveyê herikbar biguhêrîne -view-all-shortcuts = Hemû kurteriyan nîşan bide... -active-hint = Pêşniyara çalak -gaps = Valahî -floating-window-exceptions = Awarteyên çarçoveyê herikbar... -window-management-settings = Sazkariyên rêveberiya çarçoveyê... -all-workspaces = Hemû qadên xebatê -per-workspace = Li gorî qada xebatê -super = Super -shift = Shift -arrow-keys = tîr -tiled = Berhevkirî -floating = Herikbar -autotile-behavior = Li ser qadên xebatê çarçoveyan berhev bike -new-workspace = Tevgera qada xebatê ya nû diff --git a/cosmic-applet-tiling/i18n/lo/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/lo/cosmic_applet_tiling.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-tiling/i18n/nl/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/nl/cosmic_applet_tiling.ftl index 9b2c50bf..fcae7910 100644 --- a/cosmic-applet-tiling/i18n/nl/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/nl/cosmic_applet_tiling.ftl @@ -3,9 +3,9 @@ tile-current = Huidig werkblad tegelen shortcuts = Sneltoetsen navigate-windows = Tussen vensters schakelen move-window = Venster verplaatsen -toggle-floating-window = Zweven aan- of uitzetten voor venster +toggle-floating-window = Zet zwevende vensters aan/uit view-all-shortcuts = Alle sneltoetsen bekijken… -active-hint = Vensterfocus-aanduiding +active-hint = Visuele hint actief venster gaps = Ruimte rond getegelde vensters floating-window-exceptions = Uitzonderingen voor zwevende vensters… window-management-settings = Instellingen voor vensterbeheer… diff --git a/cosmic-applet-tiling/i18n/sat/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/sat/cosmic_applet_tiling.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-tiling/i18n/sr/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/sr/cosmic_applet_tiling.ftl index 394e8fd9..e69de29b 100644 --- a/cosmic-applet-tiling/i18n/sr/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/sr/cosmic_applet_tiling.ftl @@ -1,20 +0,0 @@ -arrow-keys = стрелице -tiled = Поплочано -active-hint = Активна помоћ -navigate-windows = Крећите се прозорима -toggle-floating-window = Окини пловни прозор -all-workspaces = Сви радни простори -per-workspace = По радном простору -autotile-behavior = Поплочај прозоре на радним просторима -tile-current = Поплочај тренутни радни простор -floating = Плутајуће -gaps = Размаци -move-window = Премести прозор -tile-windows = Самостално поплочај прозоре -view-all-shortcuts = Прикажи све пречице... -shortcuts = Пречице -shift = Shift -floating-window-exceptions = Изузеци за пловне прозоре... -super = Супер -window-management-settings = Подешавања за управљање прозорима... -new-workspace = Понашање новог радног простора diff --git a/cosmic-applet-tiling/src/window.rs b/cosmic-applet-tiling/src/window.rs index 912b3059..327d5d75 100644 --- a/cosmic-applet-tiling/src/window.rs +++ b/cosmic-applet-tiling/src/window.rs @@ -26,7 +26,7 @@ use cosmic::{ }; use cosmic_comp_config::{CosmicCompConfig, TileBehavior}; use cosmic_protocols::workspace::v2::client::zcosmic_workspace_handle_v2::TilingState; -use std::thread; +use std::{thread, time::Instant}; use tracing::error; const ID: &str = "com.system76.CosmicAppletTiling"; @@ -46,7 +46,6 @@ pub struct Window { } #[derive(Clone, Debug)] -#[allow(dead_code)] pub enum Message { TogglePopup, PopupClosed(Id), @@ -147,22 +146,17 @@ impl cosmic::Application for Window { return if let Some(p) = self.popup.take() { destroy_popup(p) } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - let new_id = Id::unique(); - app.popup = Some(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 new_id = Id::unique(); + self.popup = Some(new_id); + let popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, + Some((1, 1)), None, - )); + None, + ); + + get_popup(popup_settings) }; } Message::PopupClosed(id) => { diff --git a/cosmic-applet-time/Cargo.toml b/cosmic-applet-time/Cargo.toml index b2026bac..ff5e6298 100644 --- a/cosmic-applet-time/Cargo.toml +++ b/cosmic-applet-time/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-time" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -9,7 +9,7 @@ cosmic-applets-config.workspace = true jiff = "0.2" 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,5 +17,5 @@ tracing-subscriber.workspace = true tracing.workspace = true icu = { version = "2.1.1", features = ["compiled_data"] } zbus.workspace = true -timedate-zbus = { path = "../../dbus-settings-bindings/timedate" } +timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } logind-zbus = "5.3.2" diff --git a/cosmic-applet-time/i18n/ca/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/ca/cosmic_applet_time.ftl index daed32e1..e69de29b 100644 --- a/cosmic-applet-time/i18n/ca/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/ca/cosmic_applet_time.ftl @@ -1 +0,0 @@ -datetime-settings = Configuració de data, hora i calendari... diff --git a/cosmic-applet-time/i18n/de/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/de/cosmic_applet_time.ftl index e4e6c44a..e08a855a 100644 --- a/cosmic-applet-time/i18n/de/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/de/cosmic_applet_time.ftl @@ -1 +1 @@ -datetime-settings = Datum, Uhrzeit und Kalendereinstellungen ... +datetime-settings = Datum, Uhrzeit und Kalendereinstellungen... diff --git a/cosmic-applet-time/i18n/el/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/el/cosmic_applet_time.ftl index 1e7405f3..e69de29b 100644 --- a/cosmic-applet-time/i18n/el/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/el/cosmic_applet_time.ftl @@ -1 +0,0 @@ -datetime-settings = Ρυθμίσεις ημερομηνίας, ώρας και ημερολογίου... diff --git a/cosmic-applet-time/i18n/fil/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/fil/cosmic_applet_time.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-time/i18n/gl/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/gl/cosmic_applet_time.ftl deleted file mode 100644 index d00079ad..00000000 --- a/cosmic-applet-time/i18n/gl/cosmic_applet_time.ftl +++ /dev/null @@ -1 +0,0 @@ -datetime-settings = Axustes de data, hora e calendario... diff --git a/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl index e6ff41f9..e69de29b 100644 --- a/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl @@ -1 +0,0 @@ -datetime-settings = Sazkariyên dîrok, dem û salnameyê... diff --git a/cosmic-applet-time/i18n/lo/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/lo/cosmic_applet_time.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-time/i18n/sat/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/sat/cosmic_applet_time.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-time/i18n/sr/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/sr/cosmic_applet_time.ftl index 014ee726..e69de29b 100644 --- a/cosmic-applet-time/i18n/sr/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/sr/cosmic_applet_time.ftl @@ -1 +0,0 @@ -datetime-settings = Датум, време и подешавања календара... diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index e103498b..a44d81ee 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -94,7 +94,6 @@ pub struct Window { } #[derive(Debug, Clone)] -#[allow(dead_code)] pub enum Message { TogglePopup, CloseRequested(window::Id), @@ -362,7 +361,7 @@ impl cosmic::Application for Window { } fn subscription(&self) -> Subscription { - fn time_subscription(show_seconds: watch::Receiver) -> Subscription { + fn time_subscription(mut show_seconds: watch::Receiver) -> Subscription { struct Wrapper { inner: watch::Receiver, id: &'static str, @@ -377,7 +376,7 @@ impl cosmic::Application for Window { inner: show_seconds, id: "time-sub", }, - |Wrapper { inner, id: _ }| { + |Wrapper { inner, id }| { let mut show_seconds = inner.clone(); stream::channel(1, move |mut output: mpsc::Sender| async move { // Mark this receiver's state as changed so that it always receives an initial @@ -521,40 +520,35 @@ impl cosmic::Application for Window { if let Some(p) = self.popup.take() { destroy_popup(p) } else { - return cosmic::surface::surface_task(cosmic::surface::action::app_popup( - |_| Default::default(), - |app: &mut Self| { - app.date_today = app.now.date(); - app.date_selected = app.date_today; + self.date_today = self.now.date(); + self.date_selected = self.date_today; - let new_id = window::Id::unique(); - app.popup = Some(new_id); + let new_id = window::Id::unique(); + self.popup = Some(new_id); - let mut popup_settings = app.core.applet.get_popup_settings( - app.core.main_window_id().unwrap(), - new_id, - None, - None, - None, - ); - let Rectangle { - x, - y, - width, - height, - } = app.rectangle; - popup_settings.positioner.anchor_rect = Rectangle:: { - x: x.max(1.) as i32, - y: y.max(1.) as i32, - width: width.max(1.) as i32, - height: height.max(1.) as i32, - }; - - popup_settings.positioner.size = None; - popup_settings - }, + let mut popup_settings = self.core.applet.get_popup_settings( + self.core.main_window_id().unwrap(), + new_id, None, - )); + None, + None, + ); + let Rectangle { + x, + y, + width, + height, + } = self.rectangle; + popup_settings.positioner.anchor_rect = Rectangle:: { + x: x.max(1.) as i32, + y: y.max(1.) as i32, + width: width.max(1.) as i32, + height: height.max(1.) as i32, + }; + + popup_settings.positioner.size = None; + + get_popup(popup_settings) } } Message::Tick => { diff --git a/cosmic-applet-workspaces/Cargo.toml b/cosmic-applet-workspaces/Cargo.toml index dd2fb8b0..ee9e04db 100644 --- a/cosmic-applet-workspaces/Cargo.toml +++ b/cosmic-applet-workspaces/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "cosmic-applet-workspaces" -version = "1.3.0" +version = "1.0.2" authors = ["Ashley Wulber "] edition = "2024" license = "GPL-3.0-only" [dependencies] -cosmic.workspace = true +libcosmic.workspace = true cctk.workspace = true tracing.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-applet-workspaces/i18n/ca/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/ca/cosmic_applet_workspaces.ftl index 3844b7a8..e69de29b 100644 --- a/cosmic-applet-workspaces/i18n/ca/cosmic_applet_workspaces.ftl +++ b/cosmic-applet-workspaces/i18n/ca/cosmic_applet_workspaces.ftl @@ -1 +0,0 @@ -cosmic-applet-workspaces = Espais de treball del COSMIC diff --git a/cosmic-applet-workspaces/i18n/el/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/el/cosmic_applet_workspaces.ftl index 84c57d03..e69de29b 100644 --- a/cosmic-applet-workspaces/i18n/el/cosmic_applet_workspaces.ftl +++ b/cosmic-applet-workspaces/i18n/el/cosmic_applet_workspaces.ftl @@ -1 +0,0 @@ -cosmic-applet-workspaces = Χώροι εργασίας COSMIC diff --git a/cosmic-applet-workspaces/i18n/fil/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/fil/cosmic_applet_workspaces.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-workspaces/i18n/gl/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/gl/cosmic_applet_workspaces.ftl deleted file mode 100644 index a56114fd..00000000 --- a/cosmic-applet-workspaces/i18n/gl/cosmic_applet_workspaces.ftl +++ /dev/null @@ -1 +0,0 @@ -cosmic-applet-workspaces = Espazos de traballo de COSMIC diff --git a/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl index e262ce29..e69de29b 100644 --- a/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl +++ b/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl @@ -1 +0,0 @@ -cosmic-applet-workspaces = Qadên xebatê yên COSMIC diff --git a/cosmic-applet-workspaces/i18n/lo/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/lo/cosmic_applet_workspaces.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-workspaces/i18n/sat/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/sat/cosmic_applet_workspaces.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/cosmic-applet-workspaces/i18n/sr/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/sr/cosmic_applet_workspaces.ftl index 98c21cf2..e69de29b 100644 --- a/cosmic-applet-workspaces/i18n/sr/cosmic_applet_workspaces.ftl +++ b/cosmic-applet-workspaces/i18n/sr/cosmic_applet_workspaces.ftl @@ -1 +0,0 @@ -cosmic-applet-workspaces = КОСМИК радни простори diff --git a/cosmic-applet-workspaces/src/components/app.rs b/cosmic-applet-workspaces/src/components/app.rs index ddfcca20..dc4ccdc4 100644 --- a/cosmic-applet-workspaces/src/components/app.rs +++ b/cosmic-applet-workspaces/src/components/app.rs @@ -84,7 +84,6 @@ impl IcedWorkspacesApplet { } #[derive(Debug, Clone)] -#[allow(dead_code)] enum Message { WorkspaceUpdate(WorkspacesUpdate), WorkspacePressed(ExtWorkspaceHandleV1), @@ -203,20 +202,24 @@ impl cosmic::Application for IcedWorkspacesApplet { let content = column!(content, space::horizontal().width(Length::Fixed(width))) .align_x(Alignment::Center); - let btn = button(content) - .padding(if horizontal { - [0, self.core.applet.suggested_padding(true).1] + let btn = button( + container(content) + .align_x(Alignment::Center) + .align_y(Alignment::Center), + ) + .padding(if horizontal { + [0, self.core.applet.suggested_padding(true).1] + } else { + [self.core.applet.suggested_padding(true).1, 0] + }) + .on_press( + if w.state.contains(ext_workspace_handle_v1::State::Active) { + Message::WorkspaceOverview } else { - [self.core.applet.suggested_padding(true).1, 0] - }) - .on_press( - if w.state.contains(ext_workspace_handle_v1::State::Active) { - Message::WorkspaceOverview - } else { - Message::WorkspacePressed(w.handle.clone()) - }, - ) - .padding(0); + Message::WorkspacePressed(w.handle.clone()) + }, + ) + .padding(0); btn.class( if w.state.contains(ext_workspace_handle_v1::State::Active) { diff --git a/cosmic-applets-config/Cargo.toml b/cosmic-applets-config/Cargo.toml index 7ea99e7f..b6999f16 100644 --- a/cosmic-applets-config/Cargo.toml +++ b/cosmic-applets-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applets-config" -version = "1.3.0" +version = "1.0.2" edition = "2024" [dependencies] diff --git a/cosmic-applets/Cargo.toml b/cosmic-applets/Cargo.toml index d5fe4cc2..2d950afc 100644 --- a/cosmic-applets/Cargo.toml +++ b/cosmic-applets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applets" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" @@ -23,7 +23,7 @@ cosmic-applet-time = { path = "../cosmic-applet-time" } cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" } cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources" } cosmic-panel-button = { path = "../cosmic-panel-button" } -cosmic.workspace = true +libcosmic.workspace = true tracing.workspace = true tracing-subscriber.workspace = true tracing-log.workspace = true diff --git a/cosmic-applets/src/main.rs b/cosmic-applets/src/main.rs index dfd541d1..f62bbf21 100644 --- a/cosmic-applets/src/main.rs +++ b/cosmic-applets/src/main.rs @@ -12,44 +12,26 @@ fn main() -> cosmic::iced::Result { }; let start = applet.rfind('/').map_or(0, |v| v + 1); - let cmd = applet.as_str()[start..].to_string(); + let cmd = &applet.as_str()[start..]; tracing::info!("Starting `{cmd}` with version {VERSION}"); - let cmd_for_run = cmd.clone(); - let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || { - match cmd_for_run.as_str() { - "cosmic-app-list" => cosmic_app_list::run(), - "cosmic-applet-a11y" => cosmic_applet_a11y::run(), - "cosmic-applet-audio" => cosmic_applet_audio::run(), - "cosmic-applet-battery" => cosmic_applet_battery::run(), - "cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(), - "cosmic-applet-minimize" => cosmic_applet_minimize::run(), - "cosmic-applet-network" => cosmic_applet_network::run(), - "cosmic-applet-notifications" => cosmic_applet_notifications::run(), - "cosmic-applet-power" => cosmic_applet_power::run(), - "cosmic-applet-status-area" => cosmic_applet_status_area::run(), - "cosmic-applet-tiling" => cosmic_applet_tiling::run(), - "cosmic-applet-time" => cosmic_applet_time::run(), - "cosmic-applet-workspaces" => cosmic_applet_workspaces::run(), - "cosmic-applet-input-sources" => cosmic_applet_input_sources::run(), - "cosmic-panel-button" => cosmic_panel_button::run(), - _ => Ok(()), - } - })); - - match result { - Ok(r) => r, - Err(payload) => { - let msg = payload - .downcast_ref::<&str>() - .map(|s| s.to_string()) - .or_else(|| payload.downcast_ref::().cloned()) - .unwrap_or_else(|| "".to_string()); - tracing::error!( - "`{cmd}` panicked (likely compositor disconnect), exiting cleanly: {msg}" - ); - Ok(()) - } + match cmd { + "cosmic-app-list" => cosmic_app_list::run(), + "cosmic-applet-a11y" => cosmic_applet_a11y::run(), + "cosmic-applet-audio" => cosmic_applet_audio::run(), + "cosmic-applet-battery" => cosmic_applet_battery::run(), + "cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(), + "cosmic-applet-minimize" => cosmic_applet_minimize::run(), + "cosmic-applet-network" => cosmic_applet_network::run(), + "cosmic-applet-notifications" => cosmic_applet_notifications::run(), + "cosmic-applet-power" => cosmic_applet_power::run(), + "cosmic-applet-status-area" => cosmic_applet_status_area::run(), + "cosmic-applet-tiling" => cosmic_applet_tiling::run(), + "cosmic-applet-time" => cosmic_applet_time::run(), + "cosmic-applet-workspaces" => cosmic_applet_workspaces::run(), + "cosmic-applet-input-sources" => cosmic_applet_input_sources::run(), + "cosmic-panel-button" => cosmic_panel_button::run(), + _ => Ok(()), } } diff --git a/cosmic-panel-button/Cargo.toml b/cosmic-panel-button/Cargo.toml index cbb8b01a..dc6ffd9a 100644 --- a/cosmic-panel-button/Cargo.toml +++ b/cosmic-panel-button/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "cosmic-panel-button" -version = "1.3.0" +version = "1.0.2" edition = "2024" license = "GPL-3.0-only" [dependencies] -cosmic.workspace = true +libcosmic.workspace = true rustc-hash.workspace = true tracing.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-panel-button/src/lib.rs b/cosmic-panel-button/src/lib.rs index 609fe096..718744b0 100644 --- a/cosmic-panel-button/src/lib.rs +++ b/cosmic-panel-button/src/lib.rs @@ -48,7 +48,7 @@ impl Button { icon: cosmic::widget::icon::Handle, ) -> cosmic::widget::Button<'a, Message> { let theme = cosmic::theme::active(); - let _theme = theme.cosmic(); + let theme = theme.cosmic(); let suggested = self.core.applet.suggested_size(icon.symbolic); let (major_padding, applet_padding_minor_axis) = @@ -66,7 +66,7 @@ impl Button { .class(if symbolic { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::iced::widget::svg::Style { - color: Some(theme.cosmic().background(theme.transparent).on.into()), + color: Some(theme.cosmic().background.on.into()), } })) } else { @@ -123,15 +123,11 @@ impl cosmic::Application for Button { fn update(&mut self, message: Msg) -> app::Task { match message { Msg::Press => { - if let Ok(mut child) = Command::new("sh") + let _ = Command::new("sh") .arg("-c") - .arg(format!("exec {}", self.desktop.exec)) + .arg(&self.desktop.exec) .spawn() - { - std::thread::spawn(move || { - let _ = child.wait(); - }); - } + .unwrap(); } Msg::ConfigUpdated(conf) => { self.config = conf diff --git a/debian/changelog b/debian/changelog index 3d46c583..e3d8e02e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,15 +1,3 @@ -cosmic-applets (1.0.15) noble; urgency=medium - - * Update changelog - - -- Michael Murphy Thu, 28 May 2026 19:33:02 +0200 - -cosmic-applets (1.0.12) noble; urgency=medium - - * Update changelog - - -- Michael Murphy Tue, 28 Apr 2026 15:11:17 +0200 - cosmic-applets (1.0.2) noble; urgency=medium [ Ashley Wulber ] diff --git a/i18n/ca/desktop_entries.ftl b/i18n/ca/desktop_entries.ftl index 167c3614..e69de29b 100644 --- a/i18n/ca/desktop_entries.ftl +++ b/i18n/ca/desktop_entries.ftl @@ -1,2 +0,0 @@ -cosmic-app-list = Safata d'Aplicacions -cosmic-app-list-comment = Inicieu aplicacions ancorades i gestioneu les finestres obertes diff --git a/i18n/cs/desktop_entries.ftl b/i18n/cs/desktop_entries.ftl index fc451530..44354f34 100644 --- a/i18n/cs/desktop_entries.ftl +++ b/i18n/cs/desktop_entries.ftl @@ -1,4 +1,4 @@ -cosmic-app-list = Oblast aplikací +cosmic-app-list = Panel aplikací cosmic-applet-a11y = Přístupnost cosmic-applet-audio = Zvuk cosmic-applet-battery = Napájení a baterie @@ -8,7 +8,7 @@ cosmic-applet-minimize = Minimalizovaná okna cosmic-applet-network = Síť cosmic-applet-notifications = Centrum oznámení cosmic-applet-power = Uživatelská relace -cosmic-applet-status-area = Oznamovací oblast +cosmic-applet-status-area = Panel oznámení cosmic-applet-tiling = Dlaždicový režim oken cosmic-applet-time = Datum, čas a kalendář cosmic-applet-workspaces = Číslované pracovní plochy @@ -26,9 +26,9 @@ cosmic-applet-network-comment = Správa síťových připojení cosmic-applet-network-keywords = COSMIC;Applet;Síť; cosmic-applet-notifications-comment = Správa oznámení a režimu Nerušit cosmic-applet-notifications-keywords = COSMIC;Applet;Oznámení; -cosmic-applet-status-area-keywords = COSMIC;Applet;Aplikace;Indikátory;Oznámení;Notifikace;Oblast;Status;Stav; +cosmic-applet-status-area-keywords = COSMIC;Applet;Aplikace;Indikátory;Oznámení;Notifikace;Panel;Status;Stav; cosmic-app-list-comment = Správa otevřených oken a spouštění připnutých aplikací -cosmic-app-list-keywords = COSMIC;Applet;Aplikace;Oblast;Seznam;Úloha;Úlohy;Lišta; +cosmic-app-list-keywords = COSMIC;Applet;Aplikace;Panel;Seznam;Úloha;Úlohy;Lišta; cosmic-applet-a11y-comment = Konfigurace nastavení přístupnosti z panelu cosmic-applet-a11y-keywords = COSMIC;Applet;Přístupnost;A11y;Obrazovka;Obrazovky;Čtečka;Lupa;Kontrast;Barva;Barvy; cosmic-applet-audio-comment = Výběr zvukového zařízení, ovládání hlasitosti a ovládání médií MPRIS @@ -43,9 +43,9 @@ cosmic-applet-time-keywords = COSMIC;Applet;Datumy;Časy;Kalendář;Hodiny; cosmic-applet-workspaces-comment = Přepínání mezi číslovanými pracovními plochami v panelu cosmic-applet-workspaces-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy; cosmic-panel-app-button-comment = Přístup ke knihovně pro spouštění nainstalovaných aplikací -cosmic-panel-app-button-keywords = COSMIC;Applet;Aplikace;Knihovna;Oblast;Spuštění;Spouštění; +cosmic-panel-app-button-keywords = COSMIC;Applet;Aplikace;Knihovna;Panel;Spuštění;Spouštění; cosmic-panel-launcher-button-comment = Přístup ke spouštěči pro vyhledávání aplikací a spouštění příkazů cosmic-panel-launcher-button-keywords = COSMIC;Applet;Spouštěč;Vyhledávání;Příkazy; cosmic-panel-workspaces-button-comment = Přístup k přehledu pracovních ploch pro jejich správu a přepínání cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Pracovní;Plocha;Plochy;Přehled; -cosmic-applet-status-area-comment = Ikony aplikací, které mohou zobrazovat nabídky na panelu +cosmic-applet-status-area-comment = Indikátory aplikací, které mohou exportovat menu do panelu diff --git a/i18n/da/desktop_entries.ftl b/i18n/da/desktop_entries.ftl index 6026b028..e69de29b 100644 --- a/i18n/da/desktop_entries.ftl +++ b/i18n/da/desktop_entries.ftl @@ -1,51 +0,0 @@ -cosmic-app-list = Programbakke -cosmic-app-list-comment = Start fastgjorte apps og håndter åbne vinduer -cosmic-app-list-keywords = COSMIC;Applet;App;Statusområde;Liste;Opgave;Bjælke; -cosmic-applet-a11y = Tilgængelighed -cosmic-applet-a11y-comment = Konfigurer tilgængelighedsindstillinger fra panelet -cosmic-applet-a11y-keywords = COSMIC;Applet;Tilgængelighed;A11y;Skærm;Skærmlæser;Forstørrelsesglas;Kontrast;Farve; -cosmic-applet-audio = Lyd -cosmic-applet-audio-comment = Valg af lydenhed, lydstyrkekontrol og MPRIS-mediekontrol -cosmic-applet-audio-keywords = COSMIC;Applet;Lyd;Lyd;MPRIS; -cosmic-applet-battery = Strøm og batteri -cosmic-applet-battery-comment = Strømtilstande og strømspareindstillinger -cosmic-applet-battery-keywords = COSMIC;Applet;Strøm;Batteri; -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Administrer Bluetooth-enheder -cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth; -cosmic-applet-input-sources = Inputkilder -cosmic-applet-input-sources-comment = Skift mellem inputkilder -cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Kilde; -cosmic-applet-minimize = Minimerede vinduer -cosmic-applet-minimize-comment = Administrer minimerede vinduer -cosmic-applet-minimize-keywords = COSMIC;Applet;Minimer; -cosmic-applet-network = Netværk -cosmic-applet-network-comment = Administrer netværksforbindelser -cosmic-applet-network-keywords = COSMIC;Applet;Netværk; -cosmic-applet-notifications = Notifikationscenter -cosmic-applet-notifications-comment = Administrer notifikationer og Forstyr ikke -cosmic-applet-notifications-keywords = COSMIC;Applet;Notifikation; -cosmic-applet-power = Brugersession -cosmic-applet-power-comment = Låseskærm, log ud, dvale, genstart og luk ned -cosmic-applet-power-keywords = COSMIC;Applet;Bruger;Session;Lås;Log;Genstart;Luk ned;Dvale; -cosmic-applet-status-area = Notifikationsområde -cosmic-applet-status-area-comment = Programindikatorer, som kan eksportere menuer til panelet -cosmic-applet-status-area-keywords = COSMIC;Applet;App;Indikator;Notifikation;Statusområde;Status; -cosmic-applet-tiling = Opdeling -cosmic-applet-tiling-comment = Administrer aktiv hint samt automatisk opdeling for aktuelt og pr. arbejdsområde -cosmic-applet-tiling-keywords = COSMIC;Applet;Opdeling;Hint;Arbejdsområde; -cosmic-applet-time = Dato, tid og kalender -cosmic-applet-time-comment = Vis den aktuelle tid i panelet med en kalenderpopup -cosmic-applet-time-keywords = COSMIC;Applet;Dato;Tid;Kalender; -cosmic-applet-workspaces = Nummererede arbejdsområder -cosmic-applet-workspaces-comment = Skift mellem nummererede arbejdsområder i panelet -cosmic-applet-workspaces-keywords = COSMIC;Applet;Arbejdsområde; -cosmic-panel-app-button = Appbibliotek-knap -cosmic-panel-app-button-comment = Åbn applikationsbiblioteket for at starte installerede programmer -cosmic-panel-app-button-keywords = COSMIC;Applet;App;Bibliotek;Statusområde; -cosmic-panel-launcher-button = Starterknap -cosmic-panel-launcher-button-keywords = COSMIC;Applet;Starter;Kører; -cosmic-panel-workspaces-button = Arbejdsområdeknap -cosmic-panel-workspaces-button-comment = Åbn oversigten over arbejdsområder for at administrere og skifte mellem arbejdsområder -cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Arbejdsområde;Oversigt; -cosmic-panel-launcher-button-comment = Åbn starteren for at søge efter programmer og køre kommandoer diff --git a/i18n/de/desktop_entries.ftl b/i18n/de/desktop_entries.ftl index fd41e5be..6cb50a22 100644 --- a/i18n/de/desktop_entries.ftl +++ b/i18n/de/desktop_entries.ftl @@ -37,7 +37,7 @@ cosmic-app-list-comment = Angeheftete Apps starten und geöffnete Fenster verwal cosmic-applet-a11y-comment = Einstellungen für Barrierefreiheit über das Panel konfigurieren cosmic-applet-power-comment = Bildschirm sperren, abmelden, anhalten, neu starten und herunterfahren cosmic-applet-status-area = Benachrichtigungsübersicht -cosmic-applet-time-comment = Aktuelle Uhrzeit im Panel mit einem Kalender-Popup anzeigen +cosmic-applet-time-comment = Aktuelle Uhrzeit im Fenster mit einem Kalender-Popup anzeigen cosmic-panel-app-button-comment = Öffne die Anwendungsbibliothek, um installierte Anwendungen zu starten cosmic-panel-launcher-button-comment = Öffne den Starter, um nach Anwendungen zu suchen und Befehle auszuführen cosmic-panel-workspaces-button-comment = Öffne die Arbeitsflächenübersicht, um Arbeitsflächen zu verwalten und zwischen ihnen zu wechseln diff --git a/i18n/el/desktop_entries.ftl b/i18n/el/desktop_entries.ftl index fd33532d..e69de29b 100644 --- a/i18n/el/desktop_entries.ftl +++ b/i18n/el/desktop_entries.ftl @@ -1,51 +0,0 @@ -cosmic-app-list = Περιοχή εφαρμογών -cosmic-app-list-comment = Εκκίνηση καρφιτσωμένων εφαρμογών και διαχείριση ανοικτών παραθύρων -cosmic-applet-a11y = Προσβασιμότητα -cosmic-applet-audio = Ήχος -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Διαχείριση συσκευών Bluetooth -cosmic-applet-minimize = Ελαχιστοποιημένα παράθυρα -cosmic-applet-minimize-comment = Διαχείριση ελαχιστοποιημένων παραθύρων -cosmic-applet-network = Δίκτυο -cosmic-applet-network-comment = Διαχείριση συνδέσεων δικτύου -cosmic-applet-time = Ημερομηνία, ώρα και ημερολόγιο -cosmic-applet-workspaces = Αριθμημένοι χώροι εργασίας -cosmic-panel-workspaces-button = Κουμπί χώρων εργασίας -cosmic-applet-audio-comment = Επιλογή συσκευής ήχου, έλεγχος έντασης και στοιχεία ελέγχου πολυμέσων MPRIS -cosmic-applet-audio-keywords = Μικροεφαρμογή;Ήχος;COSMIC;Applet;Sound;Audio;MPRIS; -cosmic-applet-bluetooth-keywords = Μικροεφαρμογή;COSMIC;Applet;Bluetooth; -cosmic-applet-input-sources = Πηγές εισόδου -cosmic-applet-input-sources-comment = Εναλλαγή μεταξύ πηγών εισόδου -cosmic-applet-input-sources-keywords = Μικροεφαρμογή;Πηγή;Είσοδος;COSMIC;Applet;Input;Source; -cosmic-applet-minimize-keywords = Μικροεφαρμογή;Ελαχιστοποίηση;COSMIC;Applet;Minimize; -cosmic-applet-network-keywords = Μικροεφαρμογή;Δίκτυο;COSMIC;Applet;Network; -cosmic-applet-notifications = Κέντρο ειδοποιήσεων -cosmic-applet-notifications-comment = Διαχείριση ειδοποιήσεων και λειτουργία «Μην ενοχλείτε» -cosmic-applet-notifications-keywords = Μικροεφαρμογή;Ειδοποίηση;COSMIC;Applet;Notification; -cosmic-applet-power = Συνεδρία χρήστη -cosmic-applet-power-comment = Κλείδωμα οθόνης, αποσύνδεση, αναστολή, επανεκκίνηση και τερματισμός -cosmic-applet-power-keywords = Μικροεφαρμογή;Χρήστης;Συνεδρία;Κλείδωμα;Αποσύνδεση;Επανεκκίνηση;Τερματισμός;Αναστολή;COSMIC;Applet;User;Session;Lock;Log;Reboot;Shutdown;Suspend; -cosmic-applet-status-area = Περιοχή ειδοποιήσεων -cosmic-applet-workspaces-keywords = Μικροεφαρμογή;Χώρος;Εργασίας;COSMIC;Applet;Workspace; -cosmic-panel-app-button = Κουμπί βιβλιοθήκης εφαρμογών -cosmic-panel-workspaces-button-keywords = Μικροεφαρμογή;Χώρος;Εργασίας;Επισκόπηση;COSMIC;Applet;Workspace;Overview; -cosmic-app-list-keywords = Μικροεφαρμογή;Εφαρμογή;Περιοχή;Λίστα;Εργασία;Γραμμή;COSMIC;Applet;App;Tray;List;Task;Bar; -cosmic-applet-a11y-keywords = Μικροεφαρμογή;Προσβασιμότητα;Προσιτότητα;Οθόνη;Ανάγνωση;Αναγνώστης;Μεγεθυντικός;Φακός;Αντίθεση;Χρώμα;COSMIC;Applet;Accessibility;A11y;Screen;Reader;Magnifier;Contrast;Color; -cosmic-applet-battery = Ενέργεια και μπαταρία -cosmic-applet-battery-comment = Λειτουργίες ενέργειας και επιλογές εξοικονόμησης ενέργειας -cosmic-applet-battery-keywords = Μικροεφαρμογή;Ενέργεια;Ισχύς;Μπαταρία;COSMIC;Applet;Power;Battery; -cosmic-applet-status-area-keywords = Μικροεφαρμογή;Εφαρμογή;Ένδειξη;Ειδοποίηση;Περιοχή;Κατάσταση;COSMIC;Applet;App;Indicator;Notification;Tray;Status; -cosmic-applet-time-keywords = Μικροεφαρμογή;Ημερομηνία;Ώρα;Ημερολόγιο;COSMIC;Applet;Date;Time;Calendar; -cosmic-panel-app-button-comment = Άνοιγμα της βιβλιοθήκης εφαρμογών για εκκίνηση εγκατεστημένων εφαρμογών -cosmic-panel-app-button-keywords = Μικροεφαρμογή;Εφαρμογή;Βιβλιοθήκη;Περιοχή;COSMIC;Applet;App;Library;Tray; -cosmic-applet-a11y-comment = Διαμόρφωση των ρυθμίσεων προσβασιμότητας από τη γραμμή συστήματος -cosmic-applet-status-area-comment = Ενδείξεις εφαρμογών που ενδέχεται να εξάγουν μενού στη γραμμή συστήματος -cosmic-applet-tiling = Παράθεση -cosmic-applet-tiling-comment = Διαχείριση της ένδειξης ενεργού παραθύρου, αυτόματη παράθεση παραθύρων στον τρέχοντα χώρο εργασίας και ανά χώρο εργασίας -cosmic-applet-tiling-keywords = Μικροεφαρμογή;Παράθεση;Ένδειξη;Χώρος;Εργασίας;COSMIC;Applet;Tiling;Hint;Workspace; -cosmic-applet-time-comment = Προβολή της τρέχουσας ώρας στη γραμμή συστήματος με αναδυόμενο ημερολόγιο -cosmic-applet-workspaces-comment = Εναλλαγή μεταξύ των αριθμημένων χώρων εργασίας στη γραμμή συστήματος -cosmic-panel-launcher-button = Κουμπί γραμμής εκκίνησης -cosmic-panel-launcher-button-comment = Άνοιγμα της γραμμής εκκίνησης για αναζήτηση εφαρμογών και εκτέλεση εντολών -cosmic-panel-launcher-button-keywords = Μικροεφαρμογή;Μενού;Εκκίνηση;Εκτέλεση;COSMIC;Applet;Launcher;Runner; -cosmic-panel-workspaces-button-comment = Άνοιγμα των χώρων εργασίας για διαχείριση και εναλλαγή χώρων εργασίας diff --git a/i18n/en-GB/desktop_entries.ftl b/i18n/en-GB/desktop_entries.ftl index 87f50a21..e69de29b 100644 --- a/i18n/en-GB/desktop_entries.ftl +++ b/i18n/en-GB/desktop_entries.ftl @@ -1,51 +0,0 @@ -cosmic-app-list = App Tray -cosmic-app-list-comment = Launch pinned apps and manage open windows -cosmic-app-list-keywords = COSMIC;Applet;App;Tray;List;Task;Bar; -cosmic-applet-a11y = Accessibility -cosmic-applet-a11y-comment = Configure accessibility settings from the panel -cosmic-applet-a11y-keywords = COSMIC;Applet;Accessibility;A11y;Screen;Reader;Magnifier;Contrast;Colour; -cosmic-applet-audio = Sound -cosmic-applet-audio-comment = Audio device selection, volume control, and MPRIS media controls -cosmic-applet-audio-keywords = COSMIC;Applet;Sound;Audio;MPRIS; -cosmic-applet-battery = Power & Battery -cosmic-applet-battery-comment = Power modes and power saving options -cosmic-applet-battery-keywords = COSMIC;Applet;Power;Battery; -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Manage Bluetooth devices -cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth; -cosmic-applet-input-sources = Input Sources -cosmic-applet-input-sources-comment = Switch between input sources -cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Source; -cosmic-applet-minimize = Minimised Windows -cosmic-applet-minimize-comment = Manage minimised windows -cosmic-applet-minimize-keywords = COSMIC;Applet;Minimise; -cosmic-applet-network = Network -cosmic-applet-network-comment = Manage network connections -cosmic-applet-network-keywords = COSMIC;Applet;Network; -cosmic-applet-notifications = Notifications Centre -cosmic-applet-notifications-comment = Manage notifications and Do Not Disturb -cosmic-applet-notifications-keywords = COSMIC;Applet;Notification; -cosmic-applet-power = User Session -cosmic-applet-power-comment = Lock screen, log out, suspend, reboot, and shutdown -cosmic-applet-power-keywords = COSMIC;Applet;User;Session;Lock;Log out;Reboot;Shutdown;Suspend; -cosmic-applet-status-area = Notifications Tray -cosmic-applet-status-area-comment = Application indicators which may export menus to the panel -cosmic-applet-status-area-keywords = COSMIC;Applet;App;Indicator;Notification;Tray;Status; -cosmic-applet-tiling = Tiling -cosmic-applet-tiling-comment = Manage the active hint, current & per-workspace auto-tiling -cosmic-applet-tiling-keywords = COSMIC;Applet;Tiling;Hint;Workspace; -cosmic-applet-time = Date, Time & Calendar -cosmic-applet-time-comment = Display the current time in the panel with a calendar popup -cosmic-applet-time-keywords = COSMIC;Applet;Date;Time;Calendar; -cosmic-applet-workspaces = Numbered Workspaces -cosmic-applet-workspaces-comment = Switch between numbered workspaces in the panel -cosmic-applet-workspaces-keywords = COSMIC;Applet;Workspace; -cosmic-panel-app-button = App Library Button -cosmic-panel-app-button-comment = Open the application library for launching installed applications -cosmic-panel-app-button-keywords = COSMIC;Applet;App;Library;Tray; -cosmic-panel-launcher-button = Launcher Button -cosmic-panel-launcher-button-comment = Open the launcher to search applications and run commands -cosmic-panel-launcher-button-keywords = COSMIC;Applet;Launcher;Runner; -cosmic-panel-workspaces-button = Workspaces Button -cosmic-panel-workspaces-button-comment = Open the workspaces overview to manage and switch workspaces -cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Workspace;Overview; diff --git a/i18n/fa/desktop_entries.ftl b/i18n/fa/desktop_entries.ftl index 91683d53..e69de29b 100644 --- a/i18n/fa/desktop_entries.ftl +++ b/i18n/fa/desktop_entries.ftl @@ -1,5 +0,0 @@ -cosmic-app-list = نوار برنامه‌ها -cosmic-applet-a11y = دسترسی‌پذیری -cosmic-applet-audio = صدا -cosmic-applet-bluetooth = بلوتوث -cosmic-applet-bluetooth-comment = مدیریت دستگاه‌های بلوتوث diff --git a/i18n/fil/desktop_entries.ftl b/i18n/fil/desktop_entries.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/i18n/gl/desktop_entries.ftl b/i18n/gl/desktop_entries.ftl deleted file mode 100644 index 01a642f4..00000000 --- a/i18n/gl/desktop_entries.ftl +++ /dev/null @@ -1,51 +0,0 @@ -cosmic-app-list = Bandexa de aplicacións -cosmic-app-list-comment = Inicia as aplicacións fixadas e xestiona as xanelas abertas -cosmic-app-list-keywords = COSMIC;Miniaplicación;Aplicación;Bandexa;Lista;Tarefa;Barra; -cosmic-applet-a11y = Accesibilidade -cosmic-applet-a11y-comment = Configurar os axustes de accesibilidade dende o panel -cosmic-applet-a11y-keywords = COSMIC;Miniaplicación;Accesibilidade;A11y;Pantalla;Lector;Lupa;Contraste;Cor; -cosmic-applet-audio = Son -cosmic-applet-audio-comment = Selección do dispositivo de son, control do volume e controis multimedia MPRIS -cosmic-applet-audio-keywords = COSMIC;Miniaplicación;Son;Audio;MPRIS; -cosmic-applet-battery = Enerxía e Batería -cosmic-applet-battery-comment = Modos de enerxía e opcións de aforro enerxético -cosmic-applet-battery-keywords = COSMIC;Miniaplicación;Enerxía;Batería; -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Xestionar dispositivos Bluetooth -cosmic-applet-bluetooth-keywords = COSMIC;Miniaplicación;Bluetooth; -cosmic-applet-input-sources = Fontes de Entrada -cosmic-applet-input-sources-comment = Cambiar entre fontes de entrada -cosmic-applet-input-sources-keywords = COSMIC;Miniaplicación;Entrada;Fonte; -cosmic-applet-minimize = Xanelas minimizadas -cosmic-applet-minimize-comment = Xestionar xanelas minimizadas -cosmic-applet-minimize-keywords = COSMIC;Miniaplicación;Minimizar; -cosmic-applet-network = Rede -cosmic-applet-network-comment = Xestionar as conexións de rede -cosmic-applet-network-keywords = COSMIC;Miniaplicación;Rede; -cosmic-applet-notifications = Centro de notificacións -cosmic-applet-notifications-comment = Xestionar as notificacións e o modo Non molestar -cosmic-applet-notifications-keywords = COSMIC;Miniaplicación;Notificación; -cosmic-applet-power = Sesión de usuario -cosmic-applet-power-comment = Bloquear a pantalla, pechar a sesión, suspender, reiniciar e apagar -cosmic-applet-power-keywords = COSMIC;Miniaplicación;Usuario;Sesión;Bloquear;Pechar sesión;Reiniciar;Apagar;Suspender; -cosmic-applet-status-area = Bandexa de Notificacións -cosmic-applet-status-area-comment = Indicadores de aplicación que poden exportar menús ao panel -cosmic-applet-status-area-keywords = COSMIC;Miniaplicación;Aplicación;Indicador;Notificación;Bandexa;Estado; -cosmic-applet-tiling = Mosaico -cosmic-applet-tiling-comment = Xestiona a indicación activa e o mosaico automático actual e por espazo de traballo -cosmic-applet-tiling-keywords = COSMIC;Miniaplicación;Mosaico;Indicación;Espazo de traballo; -cosmic-applet-time = Data, hora e calendario -cosmic-applet-time-comment = Mostra a hora actual no panel cun calendario emerxente -cosmic-applet-time-keywords = COSMIC;Miniaplicación;Data;Hora;Calendario; -cosmic-applet-workspaces = Espazos de traballo numerados -cosmic-applet-workspaces-comment = Cambia entre os espazos de traballo numerados desde o panel -cosmic-applet-workspaces-keywords = COSMIC;Miniaplicación;Espazo de traballo; -cosmic-panel-app-button = Botón da biblioteca de aplicacións -cosmic-panel-app-button-comment = Abre a biblioteca de aplicacións para iniciar as aplicacións instaladas -cosmic-panel-app-button-keywords = COSMIC;Miniaplicación;Aplicación;Biblioteca;Bandexa; -cosmic-panel-launcher-button = Botón do lanzador -cosmic-panel-launcher-button-comment = Abre o lanzador para buscar aplicacións e executar ordes -cosmic-panel-launcher-button-keywords = COSMIC;Miniaplicación;Lanzador;Executor de ordes; -cosmic-panel-workspaces-button = Botón dos espazos de traballo -cosmic-panel-workspaces-button-comment = Abre a vista xeral dos espazos de traballo para xestionalos e cambiar entre eles -cosmic-panel-workspaces-button-keywords = COSMIC;Miniaplicación;Espazo de traballo;Vista xeral; diff --git a/i18n/hi/desktop_entries.ftl b/i18n/hi/desktop_entries.ftl index 3ece3b53..e69de29b 100644 --- a/i18n/hi/desktop_entries.ftl +++ b/i18n/hi/desktop_entries.ftl @@ -1,34 +0,0 @@ -cosmic-applet-a11y = अभिगम्यता -cosmic-applet-a11y-comment = पैनल से अभिगम्यता सेटिंग्स विन्यस्त करें -cosmic-applet-audio = ध्वनि -cosmic-applet-audio-comment = ऑडियो उपकरण चयन, ध्वनि स्तर नियंत्रण और MPRIS मीडिया नियंत्रण -cosmic-applet-battery = पावर और बैटरी -cosmic-applet-battery-comment = पावर मोड और ऊर्जा बचत विकल्प -cosmic-applet-battery-keywords = COSMIC;ऐपलेट;पावर;बैटरी -cosmic-applet-bluetooth = ब्लूटूथ -cosmic-applet-bluetooth-comment = ब्लूटूथ डिवाइस प्रबंधित करें -cosmic-applet-input-sources = इनपुट स्रोत -cosmic-applet-input-sources-comment = इनपुट स्रोतों के बीच स्विच करें -cosmic-applet-input-sources-keywords = COSMIC; Applet; इनपुट; स्रोत; -cosmic-applet-minimize = न्यूनतम की गई विंडोज़ -cosmic-applet-minimize-comment = न्यूनतम की गई विंडोज़ प्रबंधित करें -cosmic-applet-network = नेटवर्क -cosmic-applet-network-comment = नेटवर्क कनेक्शन प्रबंधित करें -cosmic-applet-notifications = नोटिफ़िकेशन सेंटर -cosmic-applet-notifications-comment = नोटिफ़िकेशन और डु नॉट डिस्टर्ब प्रबंधित करें -cosmic-applet-power = यूज़र सेशन -cosmic-applet-power-comment = स्क्रीन लॉक करें, लॉग आउट करें, सस्पेंड करें, रीबूट करें और शटडाउन करें -cosmic-applet-status-area = नोटिफ़िकेशन ट्रे -cosmic-applet-status-area-comment = एप्लिकेशन इंडिकेटर जो पैनल में मेनू एक्सपोर्ट कर सकते हैं -cosmic-applet-tiling = टाइलिंग -cosmic-applet-tiling-comment = सक्रिय हिंट, वर्तमान और प्रति-वर्कस्पेस ऑटो-टाइलिंग प्रबंधित करें -cosmic-applet-time = दिनांक, समय और कैलेंडर -cosmic-applet-time-comment = पैनल में कैलेंडर पॉपअप के साथ वर्तमान समय प्रदर्शित करें -cosmic-applet-workspaces = क्रमांकित वर्कस्पेस -cosmic-applet-workspaces-comment = पैनल में क्रमांकित वर्कस्पेस के बीच स्विच करें -cosmic-panel-app-button = ऐप लाइब्रेरी बटन -cosmic-panel-app-button-comment = इंस्टॉल किए गए एप्लिकेशन लॉन्च करने के लिए ऐप लाइब्रेरी खोलें -cosmic-panel-launcher-button = लॉन्चर बटन -cosmic-panel-launcher-button-comment = एप्लिकेशन खोजने और कमांड चलाने के लिए लॉन्चर खोलें -cosmic-panel-workspaces-button = वर्कस्पेस बटन -cosmic-panel-workspaces-button-comment = वर्कस्पेस प्रबंधित करने और उनके बीच स्विच करने के लिए वर्कस्पेस ओवरव्यू खोलें diff --git a/i18n/hu/desktop_entries.ftl b/i18n/hu/desktop_entries.ftl index 1799fcb4..8dd220f7 100644 --- a/i18n/hu/desktop_entries.ftl +++ b/i18n/hu/desktop_entries.ftl @@ -1,34 +1,34 @@ cosmic-app-list = Alkalmazástálca cosmic-applet-a11y = Akadálymentesség cosmic-applet-audio = Hang -cosmic-applet-battery = Energia és akkumulátor +cosmic-applet-battery = Energia és Akkumulátor cosmic-applet-bluetooth = Bluetooth -cosmic-applet-input-sources = Beviteli források +cosmic-applet-input-sources = Beviteli Források cosmic-applet-minimize = Minimalizált ablakok cosmic-applet-network = Hálózat cosmic-applet-notifications = Értesítési központ -cosmic-applet-power = Felhasználói munkamenet +cosmic-applet-power = Felhasználói Munkamenet cosmic-applet-status-area = Értesítési terület cosmic-applet-tiling = Csempézés -cosmic-applet-time = Dátum, idő és naptár +cosmic-applet-time = Dátum, Idő és Naptár cosmic-applet-workspaces = Számozott Munkaterületek cosmic-panel-app-button = Alkalmazáskönyvtár gomb cosmic-panel-launcher-button = Indító gomb cosmic-panel-workspaces-button = Munkaterületek gomb -cosmic-app-list-keywords = COSMIC;kisalkalmazás;alkalmazás;app;tálca;lista;sáv; -cosmic-applet-a11y-keywords = COSMIC;kisalkalmazás;akadálymentesség;akadálymentesítés;képernyő;olvasó;nagyító;szín; -cosmic-applet-audio-keywords = COSMIC;kisalkalmazás;hang;MPRIS; -cosmic-applet-battery-keywords = COSMIC;kisalkalmazás;energia;akkumulátor; +cosmic-app-list-keywords = COSMIC;Kisalkalmazás;Alkalmazás;App;Tálca;Lista;Sáv; +cosmic-applet-a11y-keywords = COSMIC;Kisalkalmazás;Akadálymentesség;Akadálymentesítés;Képernyő;Olvasó;Nagyító;Szín; +cosmic-applet-audio-keywords = COSMIC;Kisalkalmazás;Hang;MPRIS; +cosmic-applet-battery-keywords = COSMIC;Kisalkalmazás;Energia;Akkumulátor; cosmic-applet-bluetooth-comment = Bluetooth-eszközök kezelése -cosmic-applet-bluetooth-keywords = COSMIC;kisalkalmazás;bluetooth; -cosmic-applet-input-sources-keywords = COSMIC;kisalkalmazás;beviteli;forrás; -cosmic-applet-minimize-keywords = COSMIC;kisalkalmazás;minimizálás; -cosmic-applet-network-keywords = COSMIC;kisalkalmazás;hálózat;internet; -cosmic-applet-notifications-keywords = COSMIC;kisalkalmazás;értesítések; -cosmic-applet-power-keywords = COSMIC;kisalkalmazás;felhasználói munkamenet;zárolás;kijelentkezés;újraindítás;leállítás;felfüggesztés; -cosmic-panel-app-button-keywords = COSMIC;kisalkalmazás;alkalmazás;könyvtár;tálca; -cosmic-panel-launcher-button-keywords = COSMIC;kisalkalmazás;indító;futtató; -cosmic-panel-workspaces-button-keywords = COSMIC;kisalkalmazás;munkaterületek;áttekintés; +cosmic-applet-bluetooth-keywords = COSMIC;Kisalkalmazás;Bluetooth; +cosmic-applet-input-sources-keywords = COSMIC;Kisalkalmazás;Beviteli;Forrás; +cosmic-applet-minimize-keywords = COSMIC;Kisalkalmazás;Minimizálás; +cosmic-applet-network-keywords = COSMIC;Kisalkalmazás;Hálózat;Internet; +cosmic-applet-notifications-keywords = COSMIC;Kisalkalmazás;Értesítések; +cosmic-applet-power-keywords = COSMIC;Kisalkalmazás;Felhasználói munkamenet;Zárolás;Kijelentkezés;Újraindítás;Leállítás;Felfüggesztés; +cosmic-panel-app-button-keywords = COSMIC;Kisalkalmazás;Alkalmazás;Könyvtár;Tálca; +cosmic-panel-launcher-button-keywords = COSMIC;Kisalkalmazás;Indító;Futtató; +cosmic-panel-workspaces-button-keywords = COSMIC;Kisalkalmazás;Munkaterületek;Áttekintés; cosmic-applet-a11y-comment = Akadálymentességi beállítások kezelése a panelen cosmic-applet-audio-comment = Hangeszköz kiválasztása, hangerőszabályozás és MPRIS médiavezérlés cosmic-applet-battery-comment = Energiamódok és energiagazdálkodási beállítások @@ -39,13 +39,13 @@ cosmic-applet-notifications-comment = Értesítések és a Ne zavarjanak kezelé cosmic-applet-power-comment = Képernyő zárolása, kijelentkezés, felfüggesztés, újraindítás és leállítás cosmic-app-list-comment = Rögzített alkalmazások indítása és a megnyitott ablakok kezelése cosmic-applet-status-area-comment = Alkalmazásjelzők, melyek menüt is megjeleníthetnek a panelen -cosmic-applet-status-area-keywords = COSMIC;kisalkalmazás;alkalmazás;app;jelző;értesítések;tálca;állapot; -cosmic-applet-tiling-comment = Az aktív ablakkiemelés, valamint a jelenlegi és munkaterületenkénti automatikus csempézés kezelése -cosmic-applet-tiling-keywords = COSMIC;kisalkalmazás;csempézés;kiemelés;munkaterületek; +cosmic-applet-status-area-keywords = COSMIC;Kisalkalmazás;Alkalmazás;App;Jelző;Értesítések;Tálca;Állapot; +cosmic-applet-tiling-comment = Az aktív ablak kiemelésének, valamint az aktuális és munkaterületenkénti automatikus csempézés kezelése +cosmic-applet-tiling-keywords = COSMIC;Kisalkalmazás;Csempézés;Kiemelés;Munkaterületek; cosmic-applet-time-comment = Az aktuális idő megjelenítése a panelen, felugró naptárral -cosmic-applet-time-keywords = COSMIC;kisalkalmazás;dátum;idő;naptár; +cosmic-applet-time-keywords = COSMIC;Kisalkalmazás;Dátum;Idő;Naptár; cosmic-applet-workspaces-comment = Váltás számozott munkaterületek között a panelen -cosmic-applet-workspaces-keywords = COSMIC;kisalkalmazás;munkaterületek; +cosmic-applet-workspaces-keywords = COSMIC;Kisalkalmazás;Munkaterületek; cosmic-panel-app-button-comment = Az alkalmazáskönyvtár megnyitása a telepített alkalmazások indításához cosmic-panel-launcher-button-comment = Az indító megnyitása alkalmazások kereséséhez és parancsok futtatásához cosmic-panel-workspaces-button-comment = A munkaterületek áttekintőjének megnyitása munkaterületek kezeléséhez és váltásához diff --git a/i18n/it/desktop_entries.ftl b/i18n/it/desktop_entries.ftl index e15f8291..d7ca6b16 100644 --- a/i18n/it/desktop_entries.ftl +++ b/i18n/it/desktop_entries.ftl @@ -1,50 +1,16 @@ cosmic-app-list = Area applicazioni cosmic-applet-a11y = Accessibilità -cosmic-applet-audio = Suono -cosmic-applet-battery = Potenza e batteria +cosmic-applet-audio = Audio +cosmic-applet-battery = Alimentazione e batteria cosmic-applet-bluetooth = Bluetooth -cosmic-applet-input-sources = Sorgenti di input +cosmic-applet-input-sources = Sorgenti di immissione cosmic-applet-minimize = Finestre minimizzate cosmic-applet-network = Rete cosmic-applet-notifications = Centro notifiche cosmic-applet-power = Sessione utente cosmic-applet-status-area = Area notifiche -cosmic-applet-tiling = Affiancamento finestre +cosmic-applet-tiling = Tiling cosmic-applet-time = Data, ora e calendario -cosmic-applet-workspaces = Aree di lavoro numerate -cosmic-panel-launcher-button = Pulsante del launcher -cosmic-panel-workspaces-button = Pulsante aree di lavoro -cosmic-app-list-comment = Avvia le app fissate e gestisci le finestre aperte -cosmic-applet-a11y-comment = Configura le impostazioni di accessibilità dal pannello -cosmic-applet-audio-comment = Selezione dispositivi audio, controllo del volume e controlli multimediali MPRIS -cosmic-applet-battery-comment = Modalità di alimentazione e opzioni di risparmio energetico -cosmic-applet-bluetooth-comment = Gestione di dispositivi Bluetooth -cosmic-applet-input-sources-comment = Passa da una sorgente di input all’altra -cosmic-applet-minimize-comment = Gestisci le finestre minimizzate -cosmic-applet-network-comment = Gestisci le connessioni di rete -cosmic-applet-notifications-comment = Gestisci le notifiche e “Non disturbare” -cosmic-applet-power-comment = Blocca lo schermo, termina la sessione, sospendi, riavvia e spegni -cosmic-applet-status-area-comment = Indicatori di applicazioni che possono esportare menu nel pannello -cosmic-applet-tiling-comment = Gestisci il suggerimento attivo e l’affiancamento automatico corrente e per aree di lavoro -cosmic-applet-time-comment = Mostra l’ora corrente nel pannello con popup del calendario -cosmic-applet-workspaces-comment = Passa tra aree di lavoro numerate nel pannello -cosmic-panel-app-button = Pulsante della libreria delle applicazioni -cosmic-panel-app-button-comment = Apri la libreria delle applicazioni per avviare le applicazioni installate -cosmic-panel-launcher-button-comment = Apri il launcher per cercare applicazioni ed eseguire comandi -cosmic-panel-workspaces-button-comment = Apri la panoramica delle aree di lavoro per gestirle e passare da una all’altra -cosmic-app-list-keywords = COSMIC;Applet;Applicazione;Area di notifica;Elenco;Attività;Barra; -cosmic-applet-a11y-keywords = COSMIC;Applet;Accessibilità;A11y;Lettore di schermo;Lente d'ingrandimento;Contrasto;Colore; -cosmic-applet-audio-keywords = COSMIC;Applet;Suono;Audio;MPRIS; -cosmic-applet-battery-keywords = COSMIC;Applet;Potenza;Batteria; -cosmic-applet-bluetooth-keywords = COSMIC;Applet; Bluetooth; -cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Sorgente; -cosmic-applet-minimize-keywords = COSMIC;Applet;Minimizzare; -cosmic-applet-network-keywords = COSMIC;Applet;Rete; -cosmic-applet-notifications-keywords = COSMIC;Applet;Notifiche; -cosmic-applet-power-keywords = COSMIC;Applet;Utente;Sessione;Blocca;Termina sessione;Riavvia;Spegni;Sospendi; -cosmic-applet-status-area-keywords = COSMIC;Applet;Applicazione;Indicatore;Notifiche;Area;Stato; -cosmic-applet-tiling-keywords = COSMIC;Applet;Affiancamento;Suggerimento;Area di lavoro; -cosmic-applet-time-keywords = COSMIC;Applet;Data;Ora;Calendario; -cosmic-applet-workspaces-keywords = COSMIC;Applet;Area di lavoro; -cosmic-panel-app-button-keywords = COSMIC;Applet;App;Libreria;Tray; -cosmic-panel-launcher-button-keywords = COSMIC;Applet;Launcher;Runner; +cosmic-applet-workspaces = Spazi di lavoro numerati +cosmic-panel-launcher-button = Tasto Launcher +cosmic-panel-workspaces-button = Tasto Spazi di lavoro diff --git a/i18n/ja/desktop_entries.ftl b/i18n/ja/desktop_entries.ftl index c5b41c0a..e69de29b 100644 --- a/i18n/ja/desktop_entries.ftl +++ b/i18n/ja/desktop_entries.ftl @@ -1 +0,0 @@ -cosmic-applet-a11y = アクセシビリティ diff --git a/i18n/kmr/desktop_entries.ftl b/i18n/kmr/desktop_entries.ftl index 0a42fc18..e69de29b 100644 --- a/i18n/kmr/desktop_entries.ftl +++ b/i18n/kmr/desktop_entries.ftl @@ -1,51 +0,0 @@ -cosmic-applet-audio = Deng -cosmic-app-list = Destgeha sepanan -cosmic-applet-a11y = Gihîştin -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Amûrên Bluetooth bi rê ve bibe -cosmic-applet-bluetooth-keywords = COSMIC;Sepanok;Bluetooth; -cosmic-applet-input-sources = Çavkaniyên ketanê -cosmic-applet-input-sources-comment = Di navbera çavkaniyên ketanê de biguhêrîne -cosmic-applet-input-sources-keywords = COSMIC;Sepanok;Ketan;Çavkanî; -cosmic-app-list-comment = Sepanên darxistî veke û çarçoveyên vekirî bi rê ve bibe -cosmic-app-list-keywords = COSMIC;Sepanok;Sepan;Destgeh;Lîste;Erk;Bend; -cosmic-applet-a11y-comment = Sazkariyên gihîştinê ji destgehê saz bike -cosmic-applet-a11y-keywords = COSMIC;Sepanok;Gihîştin;Dîmender;A11y;Xwîner;Dîmender;Mezinker;Bijberî;Reng; -cosmic-applet-audio-comment = Hilbijartina amûra dengê, kontrola dengê, û kontrolên mediyaya MPRIS -cosmic-applet-audio-keywords = COSMIC;Sepanok;Deng;Deng;MPRIS; -cosmic-applet-battery = Hêz & Betarî -cosmic-applet-battery-comment = Awayên hêzê û vebijêrkên parastina hêzê -cosmic-applet-battery-keywords = COSMIC;Sepanok;Hêz;Betarî; -cosmic-applet-minimize = Çarçoveyên biçûk -cosmic-applet-minimize-comment = Çarçoveyên biçûk bi rê ve bibe -cosmic-applet-minimize-keywords = COSMIC;Sepanok;Biçûkkirin; -cosmic-applet-network = Tor -cosmic-applet-network-comment = Girêdanên torê bi rê ve bibe -cosmic-applet-network-keywords = COSMIC;Sepanok;Tor; -cosmic-applet-notifications = Navenda Agahdariyan -cosmic-applet-notifications-comment = Agahdarî û rawestandina balkişiyê bi rê ve bibe -cosmic-applet-notifications-keywords = COSMIC;Sepanok;Agahdarî; -cosmic-applet-power = Danaşîna bikarhêner -cosmic-applet-power-comment = Dîmenderê kilît bike, derkeve, rawestîne, ji nû ve bide destpêkirin, û vemrîne -cosmic-applet-power-keywords = COSMIC;Sepanok;Bikarhêner;Danaşîn;Kilîtkirin;Derketin;Destpêkirin;Vemirandin;Rawestandin; -cosmic-applet-status-area = Desgeha agahdariyan -cosmic-applet-status-area-comment = Nîşanderên sepanan ên ku dibe ku menuyan bo destgehê derxînin -cosmic-applet-status-area-keywords = COSMIC;Sepanok;Sepan;Nîşander;Agahdarî;Destgeh;Rewş; -cosmic-applet-tiling = Berhevkirin -cosmic-applet-tiling-comment = Berhevkirina xweber a çalak, ya niha û ya her qada xebatê bi rê ve bibe -cosmic-applet-tiling-keywords = COSMIC;Sepanok;Berhevkirin;Nîşander;Navenda xebatê; -cosmic-applet-time = Dîrok, dem & Salname -cosmic-applet-time-comment = Demê niha li ser destgehê bi salnameyeke vebûyî nîşan bide -cosmic-applet-time-keywords = COSMIC;Sepanok;Dîrok;Dem;Salname; -cosmic-applet-workspaces = Qada xebatê jimarkirî -cosmic-applet-workspaces-comment = Di navbera qada xebatê jimarkirî de di destgehê de biguherîne -cosmic-applet-workspaces-keywords = COSMIC;Sepanok;Qada xebatê; -cosmic-panel-app-button = Bişkoka pirtûkxaneya sepanan -cosmic-panel-app-button-comment = Pirtûkxaneya sepanan ji bo vekirina sepanên sazkirî veke -cosmic-panel-app-button-keywords = COSMIC;Sepanok;Sepan;Pirtûkxane;Destgeh; -cosmic-panel-launcher-button = Bişkoka destpêker -cosmic-panel-launcher-button-comment = Destpêkerê ji bo lêgerîna sepanan û xebitandina fermanan veke -cosmic-panel-launcher-button-keywords = COSMIC;Sepanok;Destpêker;Rêveber; -cosmic-panel-workspaces-button = Bişkoka qadên xebatê -cosmic-panel-workspaces-button-comment = Pêşdîtina qadên xebatê veke ji bo bi rê ve bibî û biguhêrînî -cosmic-panel-workspaces-button-keywords = COSMIC;Sepan;Qada xebatê;Pêşdîtin; diff --git a/i18n/ko/desktop_entries.ftl b/i18n/ko/desktop_entries.ftl index 17b758c9..7a9abf42 100644 --- a/i18n/ko/desktop_entries.ftl +++ b/i18n/ko/desktop_entries.ftl @@ -46,6 +46,3 @@ cosmic-panel-launcher-button-keywords = COSMIC;애플릿;런처;실행기; cosmic-panel-workspaces-button = 작업 공간 버튼 cosmic-panel-workspaces-button-comment = 작업 공간 관리 및 전환을 위해 작업 공간 개요 열기 cosmic-panel-workspaces-button-keywords = COSMIC;애플릿;작업 공간;개요; -cosmic-applet-workspaces-comment = 패널에서 번호가 지정된 작업 공간 간 전환 -cosmic-applet-tiling-comment = 활성 창 강조, 현재 및 작업 공간별 자동 타일링 관리 -cosmic-applet-workspaces = 번호가 지정된 작업 공간 diff --git a/i18n/lo/desktop_entries.ftl b/i18n/lo/desktop_entries.ftl deleted file mode 100644 index e69de29b..00000000 diff --git a/i18n/nl/desktop_entries.ftl b/i18n/nl/desktop_entries.ftl index aee16383..6a65d46b 100644 --- a/i18n/nl/desktop_entries.ftl +++ b/i18n/nl/desktop_entries.ftl @@ -8,44 +8,10 @@ cosmic-applet-minimize = Geminimaliseerde vensters cosmic-applet-network = Netwerk cosmic-applet-notifications = Meldingscentrum cosmic-applet-power = Gebruikerssessie -cosmic-applet-status-area = Statusvak +cosmic-applet-status-area = Meldingsvlak cosmic-applet-tiling = Vensters tegelen -cosmic-applet-time = Datum, tijd, en agenda +cosmic-applet-time = Datum, tijd en agenda cosmic-applet-workspaces = Genummerde werkbladen -cosmic-panel-app-button = Toepassingskiezersknop -cosmic-panel-launcher-button = Snelstarterknop -cosmic-panel-workspaces-button = Werkbladoverzichtsknop -cosmic-applet-battery-comment = Instellingen voor prestaties en energieverbruik -cosmic-applet-a11y-comment = Pas toegankelijkheidsinstellingen aan via het paneel -cosmic-applet-input-sources-comment = Schakel tussen invoerbronnen -cosmic-applet-workspaces-comment = Schakel tussen genummerde werkbladen via het paneel -cosmic-app-list-comment = Start vastgemaakte toepassingen en beheer openstaande vensters -cosmic-applet-audio-comment = Beheer audioapparaten, volume-instellingen, en mediaspelers -cosmic-applet-audio-keywords = COSMIC;Applet;Geluid;Audio;MPRIS; -cosmic-applet-battery-keywords = COSMIC;Applet;Energie;Verbruik;Energieverbruik;Batterij;Stroom; -cosmic-applet-bluetooth-comment = Beheer Bluetooth-apparaten -cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth; -cosmic-applet-input-sources-keywords = COSMIC;Applet;Invoer;Bron;Methode;Invoerbron;Invoermethode; -cosmic-applet-minimize-comment = Beheer geminimaliseerde vensters -cosmic-applet-network-comment = Beheer netwerkverbindingen -cosmic-applet-network-keywords = COSMIC;Applet;Netwerk; -cosmic-applet-notifications-comment = Beheer meldingen en niet storen -cosmic-applet-notifications-keywords = COSMIC;Applet;Melding; -cosmic-applet-power-comment = Vergrendel scherm, afmelden, slaapstand, herstarten, en afsluiten -cosmic-app-list-keywords = COSMIC;Applet;Toepassing;Taakbalk;Lijst;Taken;Balk; -cosmic-applet-a11y-keywords = COSMIC;Applets;Toegankelijkheid;A11y;Schermlezer;Vergrootglas;Contrast;Kleur; -cosmic-applet-minimize-keywords = COSMIC;Applet;Minimaliseer;Geminimaliseerd; -cosmic-applet-power-keywords = COSMIC;Applet;Gebruiker;Sessie;Vergrendelen;Afmelden;Opnieuw;Opstarten;Herstarten;Afsluiten;Slaapstand; -cosmic-applet-status-area-comment = Statusindicators met contextmenu's van toepassingen -cosmic-applet-tiling-comment = Beheer de vensterfocus-aanduiding en tegelen voor huidige en nieuwe werkbladen -cosmic-applet-tiling-keywords = COSMIC;Applet;Tegelen;Venster;Focus;Aanduiding;Werkblad; -cosmic-applet-time-comment = Toon de huidige datum en tijd met een pop-upagenda in het paneel -cosmic-applet-time-keywords = COSMIC;Applet;Datum;Tijd;Agenda; -cosmic-applet-workspaces-keywords = COSMIC;Applet;Werkblad; -cosmic-panel-app-button-comment = Open de toepassingskiezer om geïnstalleerde toepassingen te starten -cosmic-panel-app-button-keywords = COSMIC;Applet;Toepassing;Kiezer;Toepassingskiezer; -cosmic-panel-launcher-button-comment = Open de snelstarter om toepassingen te zoeken en commando's uit te voeren -cosmic-panel-launcher-button-keywords = COSMIC;Applet;Snelstarter;Uitvoeren; -cosmic-panel-workspaces-button-comment = Open het werkbladoverzicht om tussen werkbladen te schakelen en ze te beheren -cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Werkblad;Overzicht;Werkbladoverzicht; -cosmic-applet-status-area-keywords = COSMIC;Applet;Toepassing;Indicator;Status;Vak; +cosmic-panel-app-button = Knop appbibliotheek +cosmic-panel-launcher-button = Knop snelstarter +cosmic-panel-workspaces-button = Knop werkbladenoverzicht diff --git a/i18n/oc/desktop_entries.ftl b/i18n/oc/desktop_entries.ftl index 894d5e1d..e69de29b 100644 --- a/i18n/oc/desktop_entries.ftl +++ b/i18n/oc/desktop_entries.ftl @@ -1,19 +0,0 @@ -cosmic-app-list = Cinta d’aplicacions -cosmic-app-list-comment = Lançar d’aplicacions penjadas e gerir las fenèstras dobèrtas -cosmic-app-list-keywords = COSMIC;Applet;Ajuston;Microaplicacion;Miniaplicacion;App;Aplicacion;Cinta;Lista;Prètzfach;Prètzfait;Barra; -cosmic-applet-a11y = Accessibilitat -cosmic-applet-a11y-comment = Configurar los paramètres d’accessibilitat del panèl estant -cosmic-applet-audio = Son -cosmic-applet-battery = Energia e batariá -cosmic-applet-battery-comment = Mòdes d’energia e opcions d’estalvi d’energia -cosmic-applet-bluetooth = Bluetooth -cosmic-applet-bluetooth-comment = Gerir los aparelhs Bluetooth -cosmic-applet-input-sources = Fonts d’entrada -cosmic-applet-network = Ret -cosmic-applet-network-comment = Gerir las connexion ret -cosmic-applet-notifications = Centre de notificacions -cosmic-applet-notifications-comment = Gerir las notificacions e lo mòde Destorbar pas -cosmic-applet-power = Session utilizaire -cosmic-applet-status-area = Cinta de notificacions -cosmic-applet-time = Data, ora e calendièr -cosmic-applet-workspaces = Espacis de trabalha numerotats diff --git a/i18n/pt/desktop_entries.ftl b/i18n/pt/desktop_entries.ftl index 68cc145a..de93fad1 100644 --- a/i18n/pt/desktop_entries.ftl +++ b/i18n/pt/desktop_entries.ftl @@ -20,8 +20,3 @@ cosmic-applet-workspaces-comment = Alternar entre áreas de trabalho numeradas n cosmic-applet-workspaces-keywords = COSMIC;Miniaplicação;Applet;Área;Trabalho; cosmic-panel-workspaces-button-comment = Abrir a visão geral das áreas de trabalho para gerir e alternar entre elas cosmic-panel-workspaces-button-keywords = COSMIC;Miniaplicação;Applet;Área;Trabalho;Visão;Geral; -cosmic-applet-a11y-comment = Configurar definições de acessibilidade a partir do painel -cosmic-applet-battery = Energia e bateria -cosmic-app-list-keywords = COSMIC;Miniaplicação;Applet;Aplicação;Bandeja;Lista;Tarefa;Barra; -cosmic-applet-a11y-keywords = COSMIC;Miniaplicação;Applet;Acessibilidade;A11y;Ecrã;Leitor;Lupa;Ampliador;Contraste;Cor; -cosmic-applet-audio-keywords = COSMIC;Miniaplicação;Applet;Som;Áudio;MPRIS; diff --git a/i18n/sat/desktop_entries.ftl b/i18n/sat/desktop_entries.ftl deleted file mode 100644 index 3bef0114..00000000 --- a/i18n/sat/desktop_entries.ftl +++ /dev/null @@ -1,10 +0,0 @@ -cosmic-applet-a11y-keywords = COSMIC; ᱮᱯᱞᱮᱴ; ᱮᱠᱥᱮᱥᱤᱵᱤᱞᱤᱴᱤ; A11y; ᱥᱠᱨᱤᱱ; ᱨᱤᱰᱟᱨ; ᱢᱮᱜᱽᱱᱤᱯᱷᱟᱭᱟᱨ; ᱠᱚᱱᱴᱨᱟᱥᱴ; ᱨᱚᱝ; -cosmic-applet-bluetooth-comment = ᱵᱞᱩᱴᱩᱛᱷ ᱥᱟᱫᱷᱚᱱ ᱠᱚ ᱥᱚᱢᱵᱷᱲᱟᱣ ᱢᱮ -cosmic-applet-input-sources-comment = ᱤᱱᱯᱩᱴ ᱥᱚᱨᱥ ᱠᱚ ᱛᱟᱞᱟ ᱨᱮ ᱵᱚᱫᱚᱞ ᱢᱮ -cosmic-applet-input-sources-keywords = ᱠᱚᱥᱢᱤᱠ; ᱮᱯᱞᱮᱴ; ᱤᱱᱯᱩᱴ; ᱥᱨᱚᱛ; -cosmic-applet-minimize = ᱦᱩᱰᱤᱧ ᱟᱠᱟᱱ ᱡᱟᱨᱞᱟ -cosmic-applet-status-area = ᱱᱚᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱴᱨᱮ -cosmic-applet-status-area-comment = ᱮᱯᱞᱤᱠᱮᱥᱚᱱ ᱤᱱᱰᱤᱠᱮᱴᱚᱨ ᱚᱠᱟ ᱫᱚ ᱯᱮᱱᱮᱞ ᱨᱮ ᱢᱮᱱᱭᱩᱥ ᱮ ᱮᱠᱥᱯᱚᱨᱴ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ -cosmic-applet-status-area-keywords = ᱠᱚᱥᱢᱤᱠ; ᱮᱯᱞᱮᱴ; ᱮᱯ; ᱤᱱᱰᱤᱠᱮᱴᱚᱨ; ᱱᱚᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ; ᱴᱨᱮ; ᱥᱴᱮᱴᱟᱥ; -cosmic-applet-time = ᱢᱟᱦᱟᱸ, ᱚᱠᱛᱚ ᱟᱨ ᱠᱮᱞᱮᱱᱰᱟᱨ -cosmic-panel-launcher-button = ᱞᱚᱱᱪᱟᱨ ᱵᱩᱛᱟᱢ diff --git a/i18n/sr/desktop_entries.ftl b/i18n/sr/desktop_entries.ftl index 10c8d1eb..e69de29b 100644 --- a/i18n/sr/desktop_entries.ftl +++ b/i18n/sr/desktop_entries.ftl @@ -1,51 +0,0 @@ -cosmic-app-list = Системска касета -cosmic-app-list-comment = Покрени закачене програме и управљај отвореним прозорима -cosmic-app-list-keywords = COSMIC;Applet;App;Tray;List;Task;Bar;Космик;Програмчић;Програм;Касета;Списак;Задатак;Трака;kosmik;programčić;program;kaseta;spisak;zadatak;traka; -cosmic-applet-a11y = Приступачност -cosmic-applet-a11y-comment = Подеси подешавања приступачности из траке -cosmic-applet-a11y-keywords = COSMIC;Applet;Accessibility;A11y;Screen;Reader;Magnifier;Contrast;Color;Космик;Програмчић;Приступачност;А11ј;Екран;Читач;Лупа;Контраст;Боја;kosmik;programčić;pristupačnost;a11j;ekran;čitač;lupa;kontrast;boja; -cosmic-applet-audio = Звук -cosmic-applet-audio-comment = Избор уређаја звука, управљање јачином звука и MPRIS контроле медија -cosmic-applet-audio-keywords = COSMIC;Applet;Sound;Audio;MPRIS;Космик;Програмчић;Аудио;Звук;Јачина звука;МПРИС;Медија;kosmik;programčić;audio;zvuk;jačina zvuka;medija; -cosmic-applet-battery = Напајање и батерија -cosmic-applet-battery-comment = Режими напајања и могућности уштеде енергије -cosmic-applet-battery-keywords = COSMIC;Applet;Power;Battery;Космик;Програмчић;Напајање;Батерија;kosmik;programčić;napajanje;baterija; -cosmic-applet-bluetooth = Блутут -cosmic-applet-bluetooth-comment = Управљај Блутут уређајима -cosmic-applet-bluetooth-keywords = COSMIC;Applet;Bluetooth;Космик;Програмчић;Блутут;kosmik;programčić;blutut; -cosmic-applet-input-sources = Извори уноса -cosmic-applet-input-sources-comment = Пребацивање између извора уноса -cosmic-applet-input-sources-keywords = COSMIC;Applet;Input;Source;Космик;Програмчић;Унос;Извор;kosmik;programčić;unos;izvor; -cosmic-applet-minimize = Умањени прозори -cosmic-applet-minimize-comment = Управљај умањеним прозорима -cosmic-applet-minimize-keywords = COSMIC;Applet;Minimize;Космик;Програмчић;Умањи;kosmik;programčić;umanji; -cosmic-applet-network = Мрежа -cosmic-applet-network-comment = Управљај мрежним везама -cosmic-applet-network-keywords = COSMIC;Applet;Network;Космик;Програмчић;Мрежа;kosmik;programčić;mreža; -cosmic-applet-notifications = Центар за обавештења -cosmic-applet-notifications-comment = Управљај обавештењима и режимом „Не узнемиравај“ -cosmic-applet-notifications-keywords = COSMIC;Applet;Notification;Космик;Програмчић;Обавештење;kosmik;programčić;obaveštenje; -cosmic-applet-power = Корисничка сесија -cosmic-applet-power-comment = Закључај екран, одјави се, обустави, поново покрени и искључи -cosmic-applet-power-keywords = COSMIC;Applet;User;Session;Lock;Log;Reboot;Shutdown;Suspend;Космик;Програмчић;Корисник;Сесија;Закључавање;Одјава;Поновно покретање;Искључивање;Обустава;kosmik;programčić;korisnik;sesija;zaključavanje;odjava;ponovno pokretanje;isključivanje;obustava; -cosmic-applet-status-area = Обавештајна касета -cosmic-applet-status-area-comment = Показивачи програма који могу извести изборнике у површ -cosmic-applet-status-area-keywords = COSMIC;Applet;App;Indicator;Notification;Tray;Status;Космик;Програмчић;Програм;Показатељ;Обавештење;Пољце;Статус;kosmik;programčić;program;pokazatelj;obaveštenje;poljce;status; -cosmic-applet-tiling = Поплочавање -cosmic-applet-tiling-comment = Управљај активним саветом, тренутним и самопоплочавањем по радном простору -cosmic-applet-tiling-keywords = COSMIC;Applet;Tiling;Hint;Workspace;Космик;Програмчић;Поплочавање;Помоћ;Радни простор;kosmik;programčić;popločavanje;pomoć;radni prostor; -cosmic-applet-time = Датум, време и календар -cosmic-applet-time-comment = Приказује тренутно време у површи са искакућим календаром -cosmic-applet-time-keywords = COSMIC;Applet;Date;Time;Calendar;Космик;Програмчић;Датум;Време;Календар;kosmik;programčić;datum;vreme;kalendar; -cosmic-applet-workspaces = Радни простори обележени бројевима -cosmic-applet-workspaces-comment = Пребаците између радних простора обележених бројевима у траци -cosmic-applet-workspaces-keywords = COSMIC;Applet;Workspace;Космик;Програмчић;радни простор;kosmik;programčić;radni prostor; -cosmic-panel-app-button = Дугме за библиотеку програма -cosmic-panel-app-button-comment = Отвори библиотеку програма за покретање инсталираних програма -cosmic-panel-app-button-keywords = COSMIC;Applet;App;Library;Tray;Космик;Програмчић;Програм;Библиотека;Касета;kosmik;programčić;program;biblioteka;kaseta; -cosmic-panel-launcher-button = Дугме покретача -cosmic-panel-launcher-button-comment = Отвори покретач да бисте претражили програме и покренули наредбе -cosmic-panel-launcher-button-keywords = COSMIC;Applet;Launcher;Runner;Космик;Програмчић;Покретач;Покретач;kosmik;programčić;pokretač;pokretač; -cosmic-panel-workspaces-button = Дугме радних простора -cosmic-panel-workspaces-button-comment = Отвори преглед радних простора за управљање и пребацивање радних простора -cosmic-panel-workspaces-button-keywords = COSMIC;Applet;Workspace;Overview;Космик;Програмчић;радни простор;Преглед;kosmik;programčić;radni prostor;pregled; diff --git a/i18n/uk/desktop_entries.ftl b/i18n/uk/desktop_entries.ftl index 72bfb5ba..b6b177b5 100644 --- a/i18n/uk/desktop_entries.ftl +++ b/i18n/uk/desktop_entries.ftl @@ -30,7 +30,7 @@ cosmic-applet-input-sources-comment = Перемикання джерел вве cosmic-applet-input-sources-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Джерело;Введення;Розкладка;Клавіатура; cosmic-applet-minimize-comment = Керування згорнутими вікнами cosmic-applet-minimize-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Згорнути;Згорнуті;Вікна;Вікно; -cosmic-applet-network-comment = Керування мережевими з’єднаннями +cosmic-applet-network-comment = Керування мережевими підключеннями cosmic-applet-network-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Мережа;Інтернет; cosmic-applet-notifications-comment = Керування сповіщеннями та режимом Не турбувати cosmic-applet-notifications-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Сповіщення; diff --git a/i18n/zh-Hant/desktop_entries.ftl b/i18n/zh-Hant/desktop_entries.ftl index ef886f04..7bac138d 100644 --- a/i18n/zh-Hant/desktop_entries.ftl +++ b/i18n/zh-Hant/desktop_entries.ftl @@ -1,31 +1,31 @@ -cosmic-applet-a11y-keywords = COSMIC;小程式;無障礙;螢幕;閱讀器;放大鏡;對比;顏色; -cosmic-applet-audio-keywords = COSMIC;小程式;音效;音訊;MPRIS; -cosmic-applet-battery-keywords = COSMIC;小程式;電源;電池; -cosmic-applet-bluetooth-keywords = COSMIC;小程式;藍牙; -cosmic-applet-input-sources-keywords = COSMIC;小程式;輸入;輸入源; -cosmic-applet-minimize-keywords = COSMIC;小程式;最小化; +cosmic-applet-a11y-keywords = COSMIC;工具程式;無障礙;螢幕;閱讀器;放大鏡;對比;顏色; +cosmic-applet-audio-keywords = COSMIC;工具程式;音響;音頻;MPRIS; +cosmic-applet-battery-keywords = COSMIC;工具程式;電源;電池; +cosmic-applet-bluetooth-keywords = COSMIC;工具程式;藍牙; +cosmic-applet-input-sources-keywords = COSMIC;工具程式;輸入;輸入源; +cosmic-applet-minimize-keywords = COSMIC;工具程式;最小化; cosmic-applet-network-keywords = COSMIC;工具程式;網路; cosmic-applet-notifications-keywords = COSMIC;工具程式;通知; cosmic-applet-power-keywords = COSMIC;工具程式;使用者;工作階段;鎖定;登入;登出;重新啟動;關閉電源;休眠; -cosmic-app-list = 應用程式托盤 -cosmic-applet-status-area = 通知托盤 -cosmic-applet-status-area-keywords = COSMIC;小程式;應用程式;指示器;通知;托盤;狀態; +cosmic-app-list = 應用程式匣盤 +cosmic-applet-status-area = 通知匣盤 +cosmic-applet-status-area-keywords = COSMIC;工具程式;应用;應用程式;指示器;通知;匣盤;狀態; cosmic-applet-status-area-comment = 可能在面板上顯示的應用指示器 -cosmic-panel-app-button-keywords = COSMIC;小程式;應用;應用程式;庫;托盤; +cosmic-panel-app-button-keywords = COSMIC;工具程式;應用;應用程式;庫;匣盤; cosmic-panel-workspaces-button = 工作區按鈕 cosmic-applet-tiling-comment = 管理啟用提示、當前和每個工作區自動視窗平鋪 -cosmic-applet-tiling-keywords = COSMIC;小程式;平鋪;提示;工作區; +cosmic-applet-tiling-keywords = COSMIC;工具程式;平鋪;提示;工作區; cosmic-applet-time = 日期、時間與行事曆 -cosmic-applet-time-comment = 在面板上顯示目前時間,並附帶彈出式日曆視窗 -cosmic-applet-time-keywords = COSMIC;小程式;日期;時間;日曆;行事曆; +cosmic-applet-time-comment = 在面板上顯示時間以及彈出日曆 +cosmic-applet-time-keywords = COSMIC;工具程式;日期;時間;日曆;行事曆; cosmic-applet-workspaces = 工作區編號 cosmic-applet-workspaces-comment = 在面板上切換帶有編號的工作區 -cosmic-applet-workspaces-keywords = COSMIC;小程式;工作區; +cosmic-applet-workspaces-keywords = COSMIC;工具程式;工作區; cosmic-panel-app-button = 應用程式庫按鈕 cosmic-panel-app-button-comment = 啟動應用程式庫來啟動已安裝的應用程式 cosmic-panel-launcher-button = 啟動器按鈕 cosmic-panel-launcher-button-comment = 開啟啟動器以搜尋應用程式以及執行命令 -cosmic-panel-launcher-button-keywords = COSMIC;小程式;啟動器; +cosmic-panel-launcher-button-keywords = COSMIC;工具程式;啟動器; cosmic-applet-notifications-comment = 管理通知和勿擾模式 cosmic-applet-a11y = 無障礙 cosmic-applet-bluetooth-comment = 管理藍牙裝置 @@ -35,11 +35,11 @@ cosmic-applet-notifications = 通知中心 cosmic-applet-network-comment = 管理網路連接 cosmic-applet-minimize-comment = 管理最小化的視窗 cosmic-applet-bluetooth = 藍牙 -cosmic-applet-audio = 音效 +cosmic-applet-audio = 音響 cosmic-applet-minimize = 最小化視窗 cosmic-app-list-comment = 啟動釘板的應用程式並管理開啟視窗 -cosmic-app-list-keywords = COSMIC;小程式;應用程式;匣盤;列表;任務;列; -cosmic-applet-a11y-comment = 從面板設定無障礙功能 +cosmic-app-list-keywords = COSMIC;工具程式;應用程式;匣盤;列表;任務;列; +cosmic-applet-a11y-comment = 從面板調設無障礙設定 cosmic-applet-audio-comment = 音訊裝置選擇、音量控制及 MPRIS 媒體控制 cosmic-applet-input-sources = 輸入來源 cosmic-applet-input-sources-comment = 切換各輸入來源 @@ -48,4 +48,4 @@ cosmic-applet-power = 使用者工作階段 cosmic-applet-power-comment = 鎖定畫面、登出、休眠、重新啟動及關機 cosmic-applet-tiling = 平鋪 cosmic-panel-workspaces-button-comment = 啟動工作區總覽以管理和切換工作區 -cosmic-panel-workspaces-button-keywords = COSMIC;小程式;工作區;總覽; +cosmic-panel-workspaces-button-keywords = COSMIC;工具程式;工作區;總覽; diff --git a/justfile b/justfile index 99c53104..83a9f819 100644 --- a/justfile +++ b/justfile @@ -59,16 +59,13 @@ _install_status_notifier_watcher: sed "s|@bindir@|{{ prefixdir }}|" cosmic-applet-status-area/data/com.system76.CosmicStatusNotifierWatcher.service.in > cosmic-applet-status-area/data/com.system76.CosmicStatusNotifierWatcher.service install -Dm0644 cosmic-applet-status-area/data/com.system76.CosmicStatusNotifierWatcher.service {{ libdir }}/systemd/user/com.system76.CosmicStatusNotifierWatcher.service -_install_secret_agent_policy: - install -Dm0644 cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf {{ sharedir }}/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf - # Installs files into the system -install: (_install_bin 'cosmic-applets') (_link_applet 'cosmic-panel-button') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletA11y' 'cosmic-applet-a11y') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletInputSources' 'cosmic-applet-input-sources') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button') _install_metainfo _install_status_notifier_watcher _install_secret_agent_policy +install: (_install_bin 'cosmic-applets') (_link_applet 'cosmic-panel-button') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletA11y' 'cosmic-applet-a11y') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletInputSources' 'cosmic-applet-input-sources') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button') _install_metainfo _install_status_notifier_watcher # Vendor Cargo dependencies locally vendor: mkdir -p .cargo - cargo vendor --locked | head -n -1 > .cargo/config + cargo vendor | head -n -1 > .cargo/config echo 'directory = "vendor"' >> .cargo/config tar pcf vendor.tar vendor rm -rf vendor diff --git a/redeploy.sh b/redeploy.sh deleted file mode 100755 index 686bf3cb..00000000 --- a/redeploy.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -# Recompile et déploie le fork local cosmic-applets (multiplexor cosmic-applets + -# binaire séparé cosmic-app-list). -# -# Cibles : /usr/local/bin/cosmic-applets et /usr/local/bin/cosmic-app-list -# (binaires compilés manuellement, hors pacman, qui priment sur ceux du paquet -# via $PATH /usr/local/bin avant /usr/bin). -# -# Branche de déploiement : yoda-dock-magnification (contient les commits -# magnification + le fix Wayland error handling). - -set -euo pipefail - -REPO="/home/lionel/Projets/COSMIC/cosmic-applets" -TARGETS=( - "cosmic-applets" - "cosmic-app-list" - "cosmic-panel-button" -) -BIN_DIR="/usr/local/bin" - -cd "$REPO" - -echo "==> Branche actuelle : $(git branch --show-current)" -echo "==> Build release (workspace)..." -cargo build --release --workspace - -STAMP=$(date +%Y%m%d-%H%M%S) -for bin in "${TARGETS[@]}"; do - src="$REPO/target/release/$bin" - dst="$BIN_DIR/$bin" - - if [[ ! -f "$src" ]]; then - echo "!! Binaire absent après build : $src" >&2 - exit 1 - fi - - if [[ -f "$dst" ]]; then - echo "==> Backup $dst" - sudo cp -a "$dst" "${dst}.bak.${STAMP}" - fi - - echo "==> Install $src -> $dst" - sudo install -m755 "$src" "$dst" -done - -echo "==> Kill des process applet en cours (cosmic-panel relancera à la demande)" -pkill -u "$USER" -f "/usr/local/bin/cosmic-applet" || true -pkill -u "$USER" -f "/usr/local/bin/cosmic-app-list" || true -pkill -u "$USER" -f "/usr/local/bin/cosmic-panel-button" || true - -echo "==> Vérif" -for bin in "${TARGETS[@]}"; do - file "$BIN_DIR/$bin" -done -echo "OK — relogin recommandé pour repartir sur des process applet propres." diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 075062e5..ff100edc 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.93.0" +channel = "1.90.0"