From 88da7797bd72c42e4dbe0167de5be361eb93d014 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 25 May 2026 13:13:13 +0200 Subject: [PATCH 01/37] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Hosted Weblate Co-authored-by: Isaac Subirana Co-authored-by: therealmate Co-authored-by: Димко Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-audio/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-battery/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-bluetooth/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-network/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-notifications/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-power/ca/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-power/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-tiling/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/uk/ Translation: Pop OS/COSMIC Applets Desktop Entries Translation: Pop OS/COSMIC Audio Applet Translation: Pop OS/COSMIC Battery Applet Translation: Pop OS/COSMIC Bluetooth Applet Translation: Pop OS/COSMIC Network Applet Translation: Pop OS/COSMIC Notifications Applet Translation: Pop OS/COSMIC Power Applet Translation: Pop OS/COSMIC Tiling Applet --- .../i18n/hu/cosmic_applet_audio.ftl | 4 ++-- .../i18n/hu/cosmic_applet_battery.ftl | 14 +++++++------- .../i18n/hu/cosmic_applet_bluetooth.ftl | 2 +- .../i18n/hu/cosmic_applet_network.ftl | 8 ++++---- .../i18n/hu/cosmic_applet_notifications.ftl | 12 ++++++------ .../i18n/ca/cosmic_applet_power.ftl | 2 ++ .../i18n/hu/cosmic_applet_power.ftl | 2 +- .../i18n/hu/cosmic_applet_tiling.ftl | 4 ++-- i18n/hu/desktop_entries.ftl | 2 +- i18n/uk/desktop_entries.ftl | 2 +- 10 files changed, 27 insertions(+), 25 deletions(-) diff --git a/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/hu/cosmic_applet_audio.ftl index c26f9fb0..b3fdb11d 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 = PulseAudio nincs csatlakozva -no-device = Nincs kiválasztott eszköz +disconnected = A PulseAudio-kapcsolat megszakadt +no-device = Nincs eszköz kiválasztva unknown-artist = Ismeretlen diff --git a/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/hu/cosmic_applet_battery.ftl index 814d3605..01626a96 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ítsa a maximális töltési szintet 80%-ra -seconds = másodperc -minutes = perc -hours = óra +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 = ó 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-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/hu/cosmic_applet_bluetooth.ftl index ada54d0b..f12b24b3 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 = Csatlakoztatva +connected = Kapcsolódva 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-network/i18n/hu/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/hu/cosmic_applet_network.ftl index e9a61812..4ad41d3f 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élessáv engedélyezéséhez. +turn-off-airplane-mode = Kapcsold ki a Wi-Fi, Bluetooth és mobil széles sá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 = Csatlakoztatva -connecting = Csatlakozás… -connect = Csatlakozás +connected = Kapcsolódva +connecting = Kapcsolódás +connect = Kapcsolódá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-notifications/i18n/hu/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/hu/cosmic_applet_notifications.ftl index ec1f5a91..0ff88aa1 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] Most - [one] 1 órával ezelőtt - *[other] { $duration } órával ezelőtt + [0] Épp most + [one] 1 órája + *[other] { $duration } órája } minutes-ago = { $duration -> - [0] Most - [one] 1 perccel ezelőtt - *[other] { $duration } perccel ezelőtt + [0] Épp most + [one] 1 perce + *[other] { $duration } perce } show-less = Kevesebb megjelenítése show-more = { $more } további megjelenítése diff --git a/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl index 2c45ddba..c1084630 100644 --- a/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/ca/cosmic_applet_power.ftl @@ -1,2 +1,4 @@ cancel = Cancel·lar confirm = Confirmar +restart = Reinicia +suspend = Suspèn diff --git a/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/hu/cosmic_applet_power.ftl index 9019650a..9791f43f 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-tiling/i18n/hu/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/hu/cosmic_applet_tiling.ftl index 7d622463..a2d0d4bc 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 = Az ablakok lebegtetésének be- és kikapcsolása +toggle-floating-window = Lebegő ablak be/ki 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/i18n/hu/desktop_entries.ftl b/i18n/hu/desktop_entries.ftl index 637e262e..82b4bfdb 100644 --- a/i18n/hu/desktop_entries.ftl +++ b/i18n/hu/desktop_entries.ftl @@ -40,7 +40,7 @@ cosmic-applet-power-comment = Képernyő zárolása, kijelentkezés, felfüggesz 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 ablak kiemelésének, valamint az aktuális és munkaterületenkénti automatikus csempézés kezelése +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-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; diff --git a/i18n/uk/desktop_entries.ftl b/i18n/uk/desktop_entries.ftl index c6088440..72bfb5ba 100644 --- a/i18n/uk/desktop_entries.ftl +++ b/i18n/uk/desktop_entries.ftl @@ -32,7 +32,7 @@ cosmic-applet-minimize-comment = Керування згорнутими вік cosmic-applet-minimize-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Згорнути;Згорнуті;Вікна;Вікно; cosmic-applet-network-comment = Керування мережевими з’єднаннями cosmic-applet-network-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Мережа;Інтернет; -cosmic-applet-notifications-comment = Керування сповіщеннями та режимом «Не турбувати» +cosmic-applet-notifications-comment = Керування сповіщеннями та режимом Не турбувати cosmic-applet-notifications-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Сповіщення; cosmic-applet-power-comment = Блокування екрана, вихід із сеансу, призупинення, перезапуск і вимкнення cosmic-applet-power-keywords = COSMIC;КОСМІК;КОСМОС;КОСМІЧНЕ;Віджет;Віджети;Сеанс;Користувач;Блокування;Вихід;Перезапуск;Вимкнення;Призупинення;Сон; From d73ef7dcfb060bb76236e7a099adb839b6d14262 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Mon, 18 May 2026 13:53:50 -0600 Subject: [PATCH 02/37] fix: search the theme path provided by the app to find status-area icons --- .../src/components/status_menu.rs | 18 +++++++++++++----- .../src/subscriptions/status_notifier_item.rs | 7 ++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/cosmic-applet-status-area/src/components/status_menu.rs b/cosmic-applet-status-area/src/components/status_menu.rs index fedd79e4..e706f37b 100644 --- a/cosmic-applet-status-area/src/components/status_menu.rs +++ b/cosmic-applet-status-area/src/components/status_menu.rs @@ -26,6 +26,7 @@ pub struct State { expanded: Option, // TODO handle icon with multiple sizes? icon_handle: icon::Handle, + icon_theme_path: Option, click_event: Option<(i32, bool)>, } @@ -39,6 +40,7 @@ impl State { icon_handle: icon::from_name("application-default") .prefer_svg(true) .handle(), + icon_theme_path: None, click_event: None, }, iced::Task::none(), @@ -63,6 +65,7 @@ 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() { @@ -93,13 +96,18 @@ impl State { self.icon_handle = if Path::new(&icon_name).exists() { icon::from_path(Path::new(&icon_name).to_path_buf()).symbolic(true) } else { - icon::from_name(icon_name) - .prefer_svg(true) - .fallback(Some(IconFallback::Names(vec![ + let mut builder = icon::from_name(icon_name).prefer_svg(true).fallback(Some( + IconFallback::Names(vec![ "application-default".into(), "application-x-executable".into(), - ]))) - .handle() + ]), + )); + + if let Some(ref theme_path) = self.icon_theme_path { + builder = builder.with_extra_paths(vec![theme_path.clone()]); + } + + builder.handle() }; iced::Task::none() 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 fd51390e..c03f0f54 100644 --- a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs +++ b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use std::hash::Hash; +use std::path::PathBuf; use cosmic::iced::{self, Subscription}; use futures::{FutureExt, StreamExt}; @@ -27,7 +28,7 @@ pub struct Icon { pub struct IconUpdate { pub name: Option, pub pixmap: Option>, - // pub theme_path: Option, + pub theme_path: Option, } impl StatusNotifierItem { @@ -118,11 +119,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()), } } From 46a8b9182b037196bd962b01bb8d1ff12e13aa79 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Thu, 21 May 2026 18:50:03 -0600 Subject: [PATCH 03/37] chore: update libcosmic --- Cargo.lock | 93 +++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cac6c0d..0f7a41e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1408,7 +1408,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "quote", "syn", @@ -1459,7 +1459,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#9c562fe3ecf03241a46a60c0078cd6ea10bd75ce" +source = "git+https://github.com/pop-os/freedesktop-icons#739e266210d471c09af61d529d8f41dccd815b90" dependencies = [ "bstr", "btoi", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#2358f0473bf68b79f54a0906994a218de211de34" +source = "git+https://github.com/pop-os/cosmic-panel#26fee6c0c310620e8b3ce3e5fbab432248a88195" dependencies = [ "anyhow", "cosmic-config", @@ -1523,7 +1523,7 @@ dependencies = [ [[package]] name = "cosmic-pipewire" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "intmap", "libspa", @@ -1551,7 +1551,7 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1565,7 +1565,7 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1578,7 +1578,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#716da6d6af0b252e2f78aba2ad72ee19ae0241e0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#fa82bdf9fe7b5f5bd6008f32f393efd5e7a71c47" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1599,7 +1599,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "futures", "iced_futures", @@ -1612,7 +1612,7 @@ dependencies = [ [[package]] name = "cosmic-settings-network-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "bitflags 2.11.1", "cosmic-dbus-networkmanager", @@ -1631,7 +1631,7 @@ dependencies = [ [[package]] name = "cosmic-settings-sound-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "cosmic-pipewire", "futures", @@ -1646,7 +1646,7 @@ dependencies = [ [[package]] name = "cosmic-settings-upower-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#703a934b096b8681b1b8d16d8625118c8073151a" +source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" dependencies = [ "futures", "iced_futures", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "almost", "configparser", @@ -2195,9 +2195,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "endi" @@ -2629,9 +2629,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -3035,7 +3035,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "dnd", "iced_accessibility", @@ -3056,7 +3056,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "accesskit", "accesskit_winit", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3082,6 +3082,7 @@ dependencies = [ "serde", "smol_str", "thiserror 2.0.18", + "unicode-segmentation", "web-time", "window_clipboard", ] @@ -3089,7 +3090,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_core", "iced_futures", @@ -3099,7 +3100,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "futures", "iced_core", @@ -3113,7 +3114,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3134,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_graphics", "iced_runtime", @@ -3143,7 +3144,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3155,7 +3156,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3170,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bytemuck", "cosmic-text", @@ -3187,7 +3188,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3218,7 +3219,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3236,7 +3237,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4053,9 +4054,9 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285efcf12ef41bec907b3000d5ffaeb54191d4d9d83c0d6157e6cbc2db255e64" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ "bitflags 2.11.1", "libc", @@ -4103,7 +4104,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "apply", "ashpd 0.12.3", @@ -4610,9 +4611,9 @@ dependencies = [ [[package]] name = "nmrs" -version = "3.1.3" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5e0c4453d1edf1b13767c4a10905a55c847d942d751cb220a78074f194d523" +checksum = "d907d6da103106d84189d3fd229d9aac921f9131b8ba38b40341c53d24409077" dependencies = [ "async-trait", "base64", @@ -4718,9 +4719,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -5245,18 +5246,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -6040,9 +6041,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap 2.14.0", "itoa", @@ -8223,9 +8224,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -8387,7 +8388,7 @@ checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#2358f0473bf68b79f54a0906994a218de211de34" +source = "git+https://github.com/pop-os/cosmic-panel#26fee6c0c310620e8b3ce3e5fbab432248a88195" dependencies = [ "serde", "wayland-protocols-wlr", From 010931d6d025d39a13e28cb99f805d5c7f4893a3 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 26 May 2026 13:31:21 -0600 Subject: [PATCH 04/37] chore: update cosmic-freedesktop-icons to fix dropbox tray icon --- Cargo.lock | 140 ++++++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f7a41e5..49356cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -512,9 +512,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -705,9 +705,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "by_address" @@ -1408,7 +1408,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "quote", "syn", @@ -1459,7 +1459,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#739e266210d471c09af61d529d8f41dccd815b90" +source = "git+https://github.com/pop-os/freedesktop-icons#cb0a2f299dbc443697ce1674065e0d4f82915c02" dependencies = [ "bstr", "btoi", @@ -1523,7 +1523,7 @@ dependencies = [ [[package]] name = "cosmic-pipewire" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "intmap", "libspa", @@ -1551,7 +1551,7 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1565,7 +1565,7 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1599,7 +1599,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "futures", "iced_futures", @@ -1612,7 +1612,7 @@ dependencies = [ [[package]] name = "cosmic-settings-network-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "bitflags 2.11.1", "cosmic-dbus-networkmanager", @@ -1631,7 +1631,7 @@ dependencies = [ [[package]] name = "cosmic-settings-sound-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "cosmic-pipewire", "futures", @@ -1646,7 +1646,7 @@ dependencies = [ [[package]] name = "cosmic-settings-upower-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#f19da761296a28ea97d6dadc2971de0bf2c0ad85" +source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" dependencies = [ "futures", "iced_futures", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "almost", "configparser", @@ -2106,7 +2106,7 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" [[package]] name = "drm" @@ -3035,7 +3035,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "dnd", "iced_accessibility", @@ -3056,7 +3056,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "accesskit", "accesskit_winit", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3090,7 +3090,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "iced_core", "iced_futures", @@ -3100,7 +3100,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "futures", "iced_core", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "iced_graphics", "iced_runtime", @@ -3144,7 +3144,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3156,7 +3156,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3171,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "bytemuck", "cosmic-text", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3219,7 +3219,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3237,7 +3237,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3878,9 +3878,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" +checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3888,14 +3888,14 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-link 0.2.1", ] [[package]] name = "jiff-static" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" +checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a" dependencies = [ "proc-macro2", "quote", @@ -3987,9 +3987,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -4104,7 +4104,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" dependencies = [ "apply", "ashpd 0.12.3", @@ -4306,9 +4306,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "logind-zbus" @@ -5025,9 +5025,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" dependencies = [ "libc", "libredox", @@ -5626,6 +5626,16 @@ dependencies = [ "font-types", ] +[[package]] +name = "redox_event" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea3e412d205440c7b0218af26247226f979ed1201674cda7a33cc70609084b5" +dependencies = [ + "bitflags 2.11.1", + "libredox", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -7104,9 +7114,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -7117,9 +7127,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -7127,9 +7137,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7137,9 +7147,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -7150,9 +7160,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -7357,9 +7367,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -8010,7 +8020,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cfg_aliases", @@ -8036,7 +8046,7 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", "bitflags 2.11.1", @@ -8051,7 +8061,7 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -8073,7 +8083,7 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8088,7 +8098,7 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -8102,14 +8112,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "dpi", "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.5", + "redox_event", "smol_str", "tracing", "winit-core", @@ -8118,7 +8128,7 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -8138,7 +8148,7 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", "bitflags 2.11.1", @@ -8164,7 +8174,7 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", "bitflags 2.11.1", @@ -8186,7 +8196,7 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -8202,7 +8212,7 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "bytemuck", From a4e6ecb28079d645137223c630ba2b4b28020b84 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 28 May 2026 19:38:30 -0400 Subject: [PATCH 05/37] fix(network): align name with spec --- cosmic-applet-network/src/app.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index 6939f5e3..608ed79f 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -726,9 +726,10 @@ impl cosmic::Application for CosmicNetworkApplet { tasks.push(update_state(conn.clone())); tasks.push(update_devices(conn.clone())); tasks.push(load_vpns(conn)); + let uuid = uuid::Uuid::new_v4().to_string().replace("-", "_"); + let my_id = format!( - "com.system76.CosmicSettings.Applet.{}.NetworkManager.SecretAgent", - uuid::Uuid::new_v4() + "com.system76.CosmicSettings.Applet._{uuid}.NetworkManager.SecretAgent", ); tasks.push(secret_agent_task(my_id).map(Message::SecretAgent)); } From a50c3d499c948f6b794abec98dd2ea1af4a8aef1 Mon Sep 17 00:00:00 2001 From: Priyam Sarkar Date: Fri, 29 May 2026 20:43:51 +0530 Subject: [PATCH 06/37] fix(bluetooth): bluetooth toggle is off despite active connection --- cosmic-applet-bluetooth/src/bluetooth.rs | 26 +++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index b3648acd..cc3b693d 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -568,22 +568,21 @@ 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; - 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; - } + 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; } } _ = wake_up_discover_tx.send(()).await; - let _ = tx.send(BluerSessionEvent::ChangesProcessed(state)).await; } + let _ = tx.send(BluerSessionEvent::ChangesProcessed(state)).await; } }); } @@ -674,6 +673,9 @@ 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(), From c86daef96a3849f456a86471c2a34fb9f1aa6264 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 28 May 2026 19:29:36 +0200 Subject: [PATCH 07/37] build: use cargo vendor --locked --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 83a9f819..91f0958f 100644 --- a/justfile +++ b/justfile @@ -65,7 +65,7 @@ install: (_install_bin 'cosmic-applets') (_link_applet 'cosmic-panel-button') (_ # Vendor Cargo dependencies locally vendor: mkdir -p .cargo - cargo vendor | head -n -1 > .cargo/config + cargo vendor --locked | head -n -1 > .cargo/config echo 'directory = "vendor"' >> .cargo/config tar pcf vendor.tar vendor rm -rf vendor From 61bd9b0dfdd8ac2283f04bf3eeb0176e015c78f7 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 28 May 2026 19:30:23 +0200 Subject: [PATCH 08/37] chore: update dependencies with fix for battery applet panic --- Cargo.lock | 94 +++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49356cf3..99de6eb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1408,7 +1408,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "quote", "syn", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#26fee6c0c310620e8b3ce3e5fbab432248a88195" +source = "git+https://github.com/pop-os/cosmic-panel#546a6c45210574caed9a3e51446aa8ad622d3627" dependencies = [ "anyhow", "cosmic-config", @@ -1523,7 +1523,7 @@ dependencies = [ [[package]] name = "cosmic-pipewire" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "intmap", "libspa", @@ -1551,7 +1551,7 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1565,7 +1565,7 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1599,7 +1599,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "futures", "iced_futures", @@ -1612,7 +1612,7 @@ dependencies = [ [[package]] name = "cosmic-settings-network-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "bitflags 2.11.1", "cosmic-dbus-networkmanager", @@ -1631,7 +1631,7 @@ dependencies = [ [[package]] name = "cosmic-settings-sound-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "cosmic-pipewire", "futures", @@ -1646,7 +1646,7 @@ dependencies = [ [[package]] name = "cosmic-settings-upower-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#60a7de5adbb39a0939e01a6af2418221c80c2c97" +source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" dependencies = [ "futures", "iced_futures", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "almost", "configparser", @@ -2058,9 +2058,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -3035,7 +3035,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "dnd", "iced_accessibility", @@ -3056,7 +3056,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "accesskit", "accesskit_winit", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3090,7 +3090,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_core", "iced_futures", @@ -3100,7 +3100,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "futures", "iced_core", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_graphics", "iced_runtime", @@ -3144,7 +3144,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3156,7 +3156,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3171,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bytemuck", "cosmic-text", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3219,7 +3219,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3237,7 +3237,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4104,7 +4104,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#8379ae7b0b6541310a7ae7212e59714a0c31e49a" +source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "apply", "ashpd 0.12.3", @@ -4183,14 +4183,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -4404,9 +4404,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memmap2" @@ -4482,9 +4482,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "log", @@ -5628,9 +5628,9 @@ dependencies = [ [[package]] name = "redox_event" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea3e412d205440c7b0218af26247226f979ed1201674cda7a33cc70609084b5" +checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7" dependencies = [ "bitflags 2.11.1", "libredox", @@ -5647,9 +5647,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags 2.11.1", ] @@ -6278,9 +6278,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -6739,9 +6739,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap 2.14.0", "toml_datetime", @@ -8398,7 +8398,7 @@ checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#26fee6c0c310620e8b3ce3e5fbab432248a88195" +source = "git+https://github.com/pop-os/cosmic-panel#546a6c45210574caed9a3e51446aa8ad622d3627" dependencies = [ "serde", "wayland-protocols-wlr", @@ -8649,18 +8649,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" dependencies = [ "proc-macro2", "quote", From 5428a86370b86d579ba3e60d148f218d47ea5a8e Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 28 May 2026 19:34:44 +0200 Subject: [PATCH 09/37] chore: bump versions to 1.0.15 --- Cargo.lock | 36 +++++++++---------- cosmic-app-list/Cargo.toml | 2 +- .../cosmic-app-list-config/Cargo.toml | 2 +- cosmic-applet-a11y/Cargo.toml | 2 +- cosmic-applet-audio/Cargo.toml | 2 +- cosmic-applet-battery/Cargo.toml | 2 +- cosmic-applet-bluetooth/Cargo.toml | 2 +- cosmic-applet-input-sources/Cargo.toml | 2 +- cosmic-applet-minimize/Cargo.toml | 2 +- cosmic-applet-network/Cargo.toml | 2 +- cosmic-applet-notifications/Cargo.toml | 2 +- cosmic-applet-power/Cargo.toml | 2 +- cosmic-applet-status-area/Cargo.toml | 2 +- cosmic-applet-tiling/Cargo.toml | 2 +- cosmic-applet-time/Cargo.toml | 2 +- cosmic-applet-workspaces/Cargo.toml | 2 +- cosmic-applets-config/Cargo.toml | 2 +- cosmic-applets/Cargo.toml | 2 +- cosmic-panel-button/Cargo.toml | 2 +- debian/changelog | 6 ++++ 20 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99de6eb4..60a28098 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1064,7 +1064,7 @@ dependencies = [ [[package]] name = "cosmic-app-list" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-app-list-config", @@ -1091,7 +1091,7 @@ dependencies = [ [[package]] name = "cosmic-app-list-config" -version = "1.0.2" +version = "1.0.15" dependencies = [ "libcosmic", "serde", @@ -1099,7 +1099,7 @@ dependencies = [ [[package]] name = "cosmic-applet-a11y" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -1118,7 +1118,7 @@ dependencies = [ [[package]] name = "cosmic-applet-audio" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-settings-sound-subscription", "i18n-embed", @@ -1138,7 +1138,7 @@ dependencies = [ [[package]] name = "cosmic-applet-battery" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-applets-config", @@ -1163,7 +1163,7 @@ dependencies = [ [[package]] name = "cosmic-applet-bluetooth" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "bluer", @@ -1182,7 +1182,7 @@ dependencies = [ [[package]] name = "cosmic-applet-input-sources" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-comp-config", "i18n-embed", @@ -1198,7 +1198,7 @@ dependencies = [ [[package]] name = "cosmic-applet-minimize" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "i18n-embed", @@ -1216,7 +1216,7 @@ dependencies = [ [[package]] name = "cosmic-applet-network" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "async-fn-stream", @@ -1242,7 +1242,7 @@ dependencies = [ [[package]] name = "cosmic-applet-notifications" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-notifications-config", @@ -1262,7 +1262,7 @@ dependencies = [ [[package]] name = "cosmic-applet-power" -version = "1.0.2" +version = "1.0.15" dependencies = [ "i18n-embed", "i18n-embed-fl", @@ -1279,7 +1279,7 @@ dependencies = [ [[package]] name = "cosmic-applet-status-area" -version = "1.0.2" +version = "1.0.15" dependencies = [ "futures", "libcosmic", @@ -1294,7 +1294,7 @@ dependencies = [ [[package]] name = "cosmic-applet-tiling" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -1313,7 +1313,7 @@ dependencies = [ [[package]] name = "cosmic-applet-time" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-applets-config", "i18n-embed", @@ -1333,7 +1333,7 @@ dependencies = [ [[package]] name = "cosmic-applet-workspaces" -version = "1.0.2" +version = "1.0.15" dependencies = [ "anyhow", "cosmic-client-toolkit", @@ -1350,7 +1350,7 @@ dependencies = [ [[package]] name = "cosmic-applets" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-app-list", "cosmic-applet-a11y", @@ -1376,7 +1376,7 @@ dependencies = [ [[package]] name = "cosmic-applets-config" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-config", "serde", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "cosmic-panel-button" -version = "1.0.2" +version = "1.0.15" dependencies = [ "cosmic-config", "libcosmic", diff --git a/cosmic-app-list/Cargo.toml b/cosmic-app-list/Cargo.toml index 7c398b97..499d9f30 100644 --- a/cosmic-app-list/Cargo.toml +++ b/cosmic-app-list/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-app-list" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-app-list/cosmic-app-list-config/Cargo.toml b/cosmic-app-list/cosmic-app-list-config/Cargo.toml index 08d87f2e..86b302ef 100644 --- a/cosmic-app-list/cosmic-app-list-config/Cargo.toml +++ b/cosmic-app-list/cosmic-app-list-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-app-list-config" -version = "1.0.2" +version = "1.0.15" edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/cosmic-applet-a11y/Cargo.toml b/cosmic-applet-a11y/Cargo.toml index a5bb12b4..f7e3e50f 100644 --- a/cosmic-applet-a11y/Cargo.toml +++ b/cosmic-applet-a11y/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-a11y" -version = "1.0.2" +version = "1.0.15" edition = "2024" [dependencies] diff --git a/cosmic-applet-audio/Cargo.toml b/cosmic-applet-audio/Cargo.toml index 96d37cad..edf97955 100644 --- a/cosmic-applet-audio/Cargo.toml +++ b/cosmic-applet-audio/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-audio" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-battery/Cargo.toml b/cosmic-applet-battery/Cargo.toml index 2218f638..8c8f6e1d 100644 --- a/cosmic-applet-battery/Cargo.toml +++ b/cosmic-applet-battery/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-battery" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-bluetooth/Cargo.toml b/cosmic-applet-bluetooth/Cargo.toml index 03b67388..e2108576 100644 --- a/cosmic-applet-bluetooth/Cargo.toml +++ b/cosmic-applet-bluetooth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-bluetooth" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-input-sources/Cargo.toml b/cosmic-applet-input-sources/Cargo.toml index 92a7daf3..8fdb1dd9 100644 --- a/cosmic-applet-input-sources/Cargo.toml +++ b/cosmic-applet-input-sources/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-input-sources" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-minimize/Cargo.toml b/cosmic-applet-minimize/Cargo.toml index 783be11b..bd564bdf 100644 --- a/cosmic-applet-minimize/Cargo.toml +++ b/cosmic-applet-minimize/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-minimize" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-network/Cargo.toml b/cosmic-applet-network/Cargo.toml index 44f08b53..3ba86f2b 100644 --- a/cosmic-applet-network/Cargo.toml +++ b/cosmic-applet-network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-network" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-or-later" diff --git a/cosmic-applet-notifications/Cargo.toml b/cosmic-applet-notifications/Cargo.toml index 094cfa14..2e472b24 100644 --- a/cosmic-applet-notifications/Cargo.toml +++ b/cosmic-applet-notifications/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-notifications" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-power/Cargo.toml b/cosmic-applet-power/Cargo.toml index 041c0474..693692e0 100644 --- a/cosmic-applet-power/Cargo.toml +++ b/cosmic-applet-power/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-power" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-status-area/Cargo.toml b/cosmic-applet-status-area/Cargo.toml index fe85ad48..d643f70d 100644 --- a/cosmic-applet-status-area/Cargo.toml +++ b/cosmic-applet-status-area/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-status-area" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-tiling/Cargo.toml b/cosmic-applet-tiling/Cargo.toml index 23e689e0..2ce1c452 100644 --- a/cosmic-applet-tiling/Cargo.toml +++ b/cosmic-applet-tiling/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-tiling" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-time/Cargo.toml b/cosmic-applet-time/Cargo.toml index ff5e6298..a6ca4dfd 100644 --- a/cosmic-applet-time/Cargo.toml +++ b/cosmic-applet-time/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-time" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applet-workspaces/Cargo.toml b/cosmic-applet-workspaces/Cargo.toml index ee9e04db..857b668d 100644 --- a/cosmic-applet-workspaces/Cargo.toml +++ b/cosmic-applet-workspaces/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applet-workspaces" -version = "1.0.2" +version = "1.0.15" authors = ["Ashley Wulber "] edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-applets-config/Cargo.toml b/cosmic-applets-config/Cargo.toml index b6999f16..724da32a 100644 --- a/cosmic-applets-config/Cargo.toml +++ b/cosmic-applets-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applets-config" -version = "1.0.2" +version = "1.0.15" edition = "2024" [dependencies] diff --git a/cosmic-applets/Cargo.toml b/cosmic-applets/Cargo.toml index 2d950afc..c2129dff 100644 --- a/cosmic-applets/Cargo.toml +++ b/cosmic-applets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-applets" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-panel-button/Cargo.toml b/cosmic-panel-button/Cargo.toml index dc6ffd9a..9fa73486 100644 --- a/cosmic-panel-button/Cargo.toml +++ b/cosmic-panel-button/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-panel-button" -version = "1.0.2" +version = "1.0.15" edition = "2024" license = "GPL-3.0-only" diff --git a/debian/changelog b/debian/changelog index 147363a2..3d46c583 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +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 From 8981b0b48ec21ac2c93cad56d82b33c6ef705888 Mon Sep 17 00:00:00 2001 From: BrianHotopp Date: Fri, 29 May 2026 13:23:45 -0400 Subject: [PATCH 10/37] fix(network): skip assumed connections in VPN list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `cosmic-applet-network` listed every connection from `nm.list_saved_connections()` in the VPN dropdown, including the in-memory-only profiles NetworkManager auto-generates for externally-managed interfaces (e.g. a `wg-quick@wg0.service` tunnel). Toggling such an "assumed" connection off deletes it from NM — it was never persisted — leaving a dead toggle with no way back through the applet or `nmcli con up`. Skip connections flagged `unsaved` (in-memory only) at the `load_vpns()` site so they no longer get a togglable entry. The active-connections section still shows the interface as connected (read-only). One-line change in `cosmic-applet-network/src/app.rs`. ## Test plan - Built on Pop!_OS and ran the patched `cosmic-applet-network`: with `wg-quick@wg0` up and NM tracking `wg0` as connected-externally, the VPN dropdown no longer shows the destructive `wg0` toggle; the active-connections section still shows `wg0`; Wi-Fi toggling is unaffected. Co-authored-by: Claude Opus 4.7 (1M context) --- cosmic-applet-network/src/app.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index 608ed79f..a550859d 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -664,6 +664,13 @@ fn load_vpns(_conn: zbus::Connection) -> Task { let mut map: IndexMap = IndexMap::new(); for c in saved { + // Skip in-memory-only NM connections — assumed connections that NM + // auto-generated from externally-managed interfaces (e.g. one + // brought up by wg-quick@wg0.service) report unsaved=true and + // evaporate on deactivate, leaving the applet's toggle dead. + if c.unsaved { + continue; + } let uuid: UUID = Arc::from(c.uuid.as_str()); let entry = match c.summary { SettingsSummary::WireGuard { .. } => ConnectionSettings::Wireguard { id: c.id }, From 95eda4087814f624b52e97e8f65d75432fd01eb2 Mon Sep 17 00:00:00 2001 From: Michael Murphy Date: Mon, 15 Jun 2026 21:09:25 +0200 Subject: [PATCH 11/37] feat(sound): use cosmic-settings-daemon's varlink API --- Cargo.lock | 576 ++++++++++---------------- Cargo.toml | 1 + cosmic-applet-audio/Cargo.toml | 10 +- cosmic-applet-audio/src/lib.rs | 228 ++++++---- cosmic-applet-audio/src/model.rs | 393 ++++++++++++++++++ cosmic-applet-audio/src/mouse_area.rs | 2 +- 6 files changed, 762 insertions(+), 448 deletions(-) create mode 100644 cosmic-applet-audio/src/model.rs diff --git a/Cargo.lock b/Cargo.lock index 60a28098..bdd37740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,22 +192,6 @@ dependencies = [ "libc", ] -[[package]] -name = "annotate-snippets" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -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" @@ -512,9 +496,9 @@ dependencies = [ [[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" @@ -531,25 +515,6 @@ 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.1", - "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" @@ -652,7 +617,7 @@ dependencies = [ "libc", "log", "macaddr", - "nix 0.29.0", + "nix", "num-derive", "num-traits", "pin-project", @@ -705,9 +670,9 @@ dependencies = [ [[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" @@ -803,25 +768,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom 7.1.3", -] - -[[package]] -name = "cfg-expr" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368" -dependencies = [ - "smallvec", - "target-lexicon", -] - [[package]] name = "cfg-if" version = "1.0.4" @@ -856,17 +802,6 @@ dependencies = [ "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" @@ -977,21 +912,6 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" -[[package]] -name = "convert_case" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -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" version = "0.9.4" @@ -1120,9 +1040,11 @@ dependencies = [ name = "cosmic-applet-audio" version = "1.0.15" dependencies = [ - "cosmic-settings-sound-subscription", + "cosmic-settings-audio-client", + "futures", "i18n-embed", "i18n-embed-fl", + "intmap", "libcosmic", "mpris2-zbus", "rust-embed", @@ -1134,6 +1056,7 @@ dependencies = [ "url", "urlencoding", "zbus", + "zlink", ] [[package]] @@ -1408,7 +1331,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1429,7 +1352,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "quote", "syn", @@ -1438,7 +1361,7 @@ dependencies = [ [[package]] name = "cosmic-dbus-a11y" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -1446,7 +1369,7 @@ dependencies = [ [[package]] name = "cosmic-dbus-networkmanager" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "bitflags 2.11.1", "derive_builder", @@ -1520,20 +1443,6 @@ dependencies = [ "xdg-shell-wrapper-config", ] -[[package]] -name = "cosmic-pipewire" -version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" -dependencies = [ - "intmap", - "libspa", - "libspa-sys", - "pipewire", - "serde", - "serde_json", - "tracing", -] - [[package]] name = "cosmic-protocols" version = "0.2.0" @@ -1551,7 +1460,7 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" +source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1565,7 +1474,7 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" +source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1575,6 +1484,33 @@ dependencies = [ "zbus", ] +[[package]] +name = "cosmic-settings-audio-client" +version = "1.0.0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#e7936f0d4f01c8c5a436908c7ee9f6ad43e6a7d8" +dependencies = [ + "cosmic-settings-audio-core", + "dirs", + "futures-util", + "ron 0.12.1", + "serde", + "tokio", + "tokio-util", + "tracing", + "zlink", +] + +[[package]] +name = "cosmic-settings-audio-core" +version = "1.0.0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#e7936f0d4f01c8c5a436908c7ee9f6ad43e6a7d8" +dependencies = [ + "dirs", + "ron 0.12.1", + "serde", + "zlink", +] + [[package]] name = "cosmic-settings-config" version = "0.1.0" @@ -1591,7 +1527,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -1599,7 +1535,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" +source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "futures", "iced_futures", @@ -1612,13 +1548,13 @@ dependencies = [ [[package]] name = "cosmic-settings-network-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" +source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "bitflags 2.11.1", "cosmic-dbus-networkmanager", "futures", "iced_futures", - "itertools 0.14.0", + "itertools", "nm-secret-agent-manager", "secret-service", "secure-string", @@ -1628,25 +1564,10 @@ dependencies = [ "zbus", ] -[[package]] -name = "cosmic-settings-sound-subscription" -version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" -dependencies = [ - "cosmic-pipewire", - "futures", - "intmap", - "libcosmic", - "numtoa", - "rustix 1.1.4", - "tokio", - "tracing", -] - [[package]] name = "cosmic-settings-upower-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#81912bed6cdebe2719e29e6bd1453e7b977acb0e" +source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "futures", "iced_futures", @@ -1684,7 +1605,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "almost", "configparser", @@ -2041,7 +1962,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2058,9 +1979,9 @@ 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", @@ -2195,9 +2116,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" @@ -2239,7 +2160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2327,7 +2248,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2" dependencies = [ - "toml 0.5.11", + "toml", ] [[package]] @@ -2531,7 +2452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6d3a3635983a889f065aa9ce760384713f23a9b4a04f696f86c39a5d7a6a5a" dependencies = [ "indexmap 2.14.0", - "nom 8.0.0", + "nom", ] [[package]] @@ -2629,9 +2550,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.4" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" @@ -2753,12 +2674,6 @@ 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" @@ -3035,7 +2950,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "dnd", "iced_accessibility", @@ -3056,7 +2971,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "accesskit", "accesskit_winit", @@ -3065,7 +2980,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3090,7 +3005,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_core", "iced_futures", @@ -3100,7 +3015,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "futures", "iced_core", @@ -3114,7 +3029,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3135,7 +3050,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_graphics", "iced_runtime", @@ -3144,7 +3059,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3156,7 +3071,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3171,7 +3086,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bytemuck", "cosmic-text", @@ -3188,7 +3103,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3219,7 +3134,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3237,7 +3152,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3846,15 +3761,6 @@ 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" @@ -3878,9 +3784,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.27" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3888,14 +3794,14 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-link 0.2.1", + "windows-sys 0.59.0", ] [[package]] name = "jiff-static" -version = "0.2.27" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", @@ -3987,9 +3893,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -4039,7 +3945,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a1886916523694cd6ea3d175f03a1e5010699a2a4cc13696d83d7bea1d80638" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4104,7 +4010,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "apply", "ashpd 0.12.3", @@ -4190,35 +4096,7 @@ dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.8.0", -] - -[[package]] -name = "libspa" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4" -dependencies = [ - "bitflags 2.11.1", - "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", + "redox_syscall 0.8.1", ] [[package]] @@ -4306,9 +4184,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.30" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "logind-zbus" @@ -4404,9 +4282,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -4464,12 +4342,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -4482,9 +4354,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", @@ -4505,7 +4377,7 @@ dependencies = [ [[package]] name = "mpris2-zbus" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "futures-util", "jiff", @@ -4589,31 +4461,19 @@ dependencies = [ "libc", ] -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.11.1", - "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" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] [[package]] name = "nmrs" -version = "3.1.5" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d907d6da103106d84189d3fd229d9aac921f9131b8ba38b40341c53d24409077" +checksum = "f9493a0dfbe50783b53ef52ec8ddb8d1f85fd45098be8210205236ff0f43bb7b" dependencies = [ "async-trait", "base64", @@ -4629,16 +4489,6 @@ dependencies = [ "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]] name = "nom" version = "8.0.0" @@ -4681,7 +4531,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4797,12 +4647,6 @@ dependencies = [ "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" @@ -5025,9 +4869,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.55" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329" dependencies = [ "libc", "libredox", @@ -5287,34 +5131,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pipewire" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44" -dependencies = [ - "anyhow", - "bitflags 2.11.1", - "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.33" @@ -5647,9 +5463,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" +checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ "bitflags 2.11.1", ] @@ -5881,7 +5697,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5908,6 +5724,12 @@ 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" @@ -6051,9 +5873,9 @@ dependencies = [ [[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", @@ -6074,15 +5896,6 @@ dependencies = [ "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.20.0" @@ -6278,9 +6091,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", @@ -6410,7 +6223,7 @@ dependencies = [ [[package]] name = "switcheroo-control" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -6446,19 +6259,6 @@ 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" @@ -6471,12 +6271,6 @@ 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" @@ -6490,10 +6284,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.3.4", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6588,7 +6382,7 @@ dependencies = [ [[package]] name = "timedate-zbus" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -6702,6 +6496,20 @@ 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]] @@ -6713,21 +6521,6 @@ 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", -] - [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -6739,9 +6532,9 @@ 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", @@ -6758,12 +6551,6 @@ dependencies = [ "winnow", ] -[[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" @@ -6982,7 +6769,7 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "upower_dbus" version = "0.3.2" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "serde", "serde_repr", @@ -7066,12 +6853,6 @@ 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" @@ -7114,9 +6895,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -7127,9 +6908,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -7137,9 +6918,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7147,9 +6928,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -7160,9 +6941,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -7367,9 +7148,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -7563,7 +7344,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -8649,18 +8430,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.49" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.49" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -8729,6 +8510,73 @@ dependencies = [ "syn", ] +[[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", +] + +[[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", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/Cargo.toml b/Cargo.toml index 569cb3b4..f97b6b28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ tokio = { version = "1.49.0", features = ["full"] } # 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 diff --git a/cosmic-applet-audio/Cargo.toml b/cosmic-applet-audio/Cargo.toml index edf97955..c47da57b 100644 --- a/cosmic-applet-audio/Cargo.toml +++ b/cosmic-applet-audio/Cargo.toml @@ -5,11 +5,11 @@ edition = "2024" license = "GPL-3.0-only" [dependencies] +futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true 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,7 +19,9 @@ tracing.workspace = true url = "2" urlencoding = "2.1.3" zbus.workspace = true +zlink.workspace = true +intmap = "3.1.3" -[dependencies.cosmic-settings-sound-subscription] -git = "https://github.com/pop-os/cosmic-settings" -# path = "../../cosmic-settings/subscriptions/sound" +[dependencies.cosmic-settings-audio-client] +git = "https://github.com/pop-os/cosmic-settings-daemon" +features = ["codec"] diff --git a/cosmic-applet-audio/src/lib.rs b/cosmic-applet-audio/src/lib.rs index 5f49d0f9..3fd7b963 100644 --- a/cosmic-applet-audio/src/lib.rs +++ b/cosmic-applet-audio/src/lib.rs @@ -2,12 +2,13 @@ // 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::{ - Element, Renderer, Task, Theme, app, + Apply, Element, Renderer, Task, Theme, app, applet::{ column as applet_column, cosmic_panel_config::PanelAnchor, @@ -26,10 +27,12 @@ use cosmic::{ surface, theme, widget::{Row, button, container, divider, icon, space, text, toggler}, }; -use cosmic_settings_sound_subscription as css; +use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy}; +use futures::SinkExt; use iced::platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup}; use mpris_subscription::{MprisRequest, MprisUpdate}; use mpris2_zbus::player::PlaybackStatus; +use std::{cell::RefCell, rc::Rc, sync::Arc}; mod config; mod mpris_subscription; @@ -50,8 +53,10 @@ pub struct Audio { core: cosmic::app::Core, /// Track the applet's popup window. popup: Option, - /// The model from cosmic-settings for managing pipewire devices. - model: css::Model, + /// Varlink connection to `com.system76.CosmicSettings.Audio`. + audio_client: Option>>, + /// Known audio device state + model: model::Model, /// Whether to expand the revealer of a source or sink device. is_open: IsOpen, /// Max slider volume for the sink device, as determined by the amplification property. @@ -72,8 +77,8 @@ pub struct Audio { impl Audio { fn output_icon_name(&self) -> &'static str { - let volume = self.model.sink_volume; - let mute = self.model.sink_mute; + let volume = self.model.active_sink.volume; + let mute = self.model.active_sink.mute; if mute || volume == 0 { "audio-volume-muted-symbolic" } else if volume < 33 { @@ -88,8 +93,8 @@ impl Audio { } fn input_icon_name(&self) -> &'static str { - let volume = self.model.source_volume; - let mute = self.model.source_mute; + let volume = self.model.active_source.volume; + let mute = self.model.active_source.mute; if mute || volume == 0 { "microphone-sensitivity-muted-symbolic" } else if volume < 33 { @@ -110,8 +115,10 @@ enum IsOpen { Input, } -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] pub enum Message { + /// Connection to `com.system76.CosmicSettings`. + Client(Arc), Ignore, SetSinkVolume(u32), SetSourceVolume(u32), @@ -129,7 +136,7 @@ pub enum Message { MprisRequest(MprisRequest), Token(TokenUpdate), OpenSettings, - Subscription(css::Message), + Subscription(audio_client::Event), Surface(surface::Action), } @@ -242,15 +249,9 @@ 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 model = css::Model::default(); - model.unplugged_text = "Unplugged".into(); - model.hd_audio_text = "HD Audio".into(); - model.usb_audio_text = "USB Audio".into(); - ( Self { core, - model, ..Default::default() }, Task::none(), @@ -318,52 +319,74 @@ impl cosmic::Application for Audio { } } Message::Subscription(message) => { - return self - .model - .update(message) - .map(|message| Message::Subscription(message).into()); + self.model.update(message); } Message::SetDefaultSink(pos) => { - return self - .model - .set_default_sink(pos) - .map(|message| Message::Subscription(message).into()); + 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.borrow_mut().conn.set_default(node_id, true).await; + }); + } } Message::SetDefaultSource(pos) => { - return self - .model - .set_default_source(pos) - .map(|message| Message::Subscription(message).into()); + 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.borrow_mut().conn.set_default(node_id, true).await; + }); + } } - Message::ToggleSinkMute => self.model.toggle_sink_mute(), + Message::ToggleSinkMute => { + if let Some(ref mut client) = self.audio_client { + futures::executor::block_on(async { + _ = client.borrow_mut().conn.sink_mute_toggle().await; + }); + } + } - Message::ToggleSourceMute => self.model.toggle_source_mute(), + Message::ToggleSourceMute => { + if let Some(ref mut client) = self.audio_client { + futures::executor::block_on(async { + _ = client.borrow_mut().conn.source_mute_toggle().await; + }); + } + } Message::SetSinkVolume(volume) => { - return self - .model - .set_sink_volume(volume) - .map(|message| Message::Subscription(message).into()); + if let Some(ref mut client) = self.audio_client { + self.model.active_sink.volume = volume; + self.model.active_sink.volume_text = volume.to_string(); + futures::executor::block_on(async { + _ = client.borrow_mut().conn.set_sink_volume(volume).await; + }); + } } Message::SetSourceVolume(volume) => { - return self - .model - .set_source_volume(volume) - .map(|message| Message::Subscription(message).into()); + if let Some(ref mut client) = self.audio_client { + self.model.active_source.volume = volume; + self.model.active_source.volume_text = volume.to_string(); + futures::executor::block_on(async { + _ = client.borrow_mut().conn.set_source_volume(volume).await; + }); + } } 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) { - if let Err(err) = self.config.write_entry(&helper) { - tracing::error!(?err, "Error writing config"); - } + tracing::error!(?err, "Error writing config"); } } Message::CloseRequested(id) => { @@ -461,6 +484,12 @@ 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(Rc::new(RefCell::new(client))); + self.model = model::Model::default(); + } + } } Task::none() @@ -476,7 +505,49 @@ impl cosmic::Application for Audio { }), mpris_subscription::mpris_subscription(0).map(Message::Mpris), activation_token_subscription(0).map(Message::Token), - Subscription::run(|| css::watch().map(Message::Subscription)), + 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"); + } + } + } + } + } + }, + ) + }), ]) } @@ -497,7 +568,7 @@ impl cosmic::Application for Audio { return Message::Ignore; } - let new_volume = (self.model.sink_volume as f64 + (scroll_vector as f64)) + let new_volume = (self.model.active_sink.volume as f64 + (scroll_vector as f64)) .clamp(0.0, self.max_sink_volume as f64); Message::SetSinkVolume(new_volume as u32) }); @@ -551,19 +622,21 @@ impl cosmic::Application for Audio { space_xxs, space_s, .. } = theme::active().cosmic().spacing; - let sink = self + let sink: Option<&str> = self .model - .active_sink() - .and_then(|pos| self.model.sinks().get(pos)); - let source = self + .sinks + .active() + .map(|pos| self.model.sinks.sorted_display[pos].as_ref()); + let source: Option<&str> = self .model - .active_source() - .and_then(|pos| self.model.sources().get(pos)); + .sources + .active() + .map(|pos| self.model.sources.sorted_display[pos].as_ref()); let mut audio_content = { let output_slider = slider( 0..=self.max_sink_volume, - self.model.sink_volume, + self.model.active_sink.volume, Message::SetSinkVolume, ) .width(Length::FillPortion(5)) @@ -571,7 +644,7 @@ impl cosmic::Application for Audio { let input_slider = slider( 0..=self.max_source_volume, - self.model.source_volume, + self.model.active_source.volume, Message::SetSourceVolume, ) .width(Length::FillPortion(5)) @@ -590,7 +663,7 @@ impl cosmic::Application for Audio { .line_height(24) .on_press(Message::ToggleSinkMute), output_slider, - container(text(&self.model.sink_volume_text).size(16)) + container(text(&self.model.active_sink.volume_text).size(16)) .width(Length::FillPortion(1)) .align_x(Alignment::End) ] @@ -609,7 +682,7 @@ impl cosmic::Application for Audio { .line_height(24) .on_press(Message::ToggleSourceMute), input_slider, - container(text(&self.model.source_volume_text).size(16)) + container(text(&self.model.active_source.volume_text).size(16)) .width(Length::FillPortion(1)) .align_x(Alignment::End) ] @@ -624,7 +697,7 @@ impl cosmic::Application for Audio { Some(sink) => sink.to_owned(), None => fl!("no-device"), }, - self.model.sinks(), + &self.model.sinks.sorted_display, Message::OutputToggle, Message::SetDefaultSink, ), @@ -635,7 +708,7 @@ impl cosmic::Application for Audio { Some(source) => source.to_owned(), None => fl!("no-device"), }, - self.model.sources(), + &self.model.sources.sorted_display, Message::InputToggle, Message::SetDefaultSource, ) @@ -691,19 +764,15 @@ 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 }) - .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(), + 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(), ); } if let Some(go_next) = self.go_next(32) { @@ -754,20 +823,21 @@ impl cosmic::Application for Audio { } } -fn revealer( +fn revealer<'a>( open: bool, title: String, selected: String, - devices: &[String], + devices: &'a [Arc], toggle: Message, mut change: impl FnMut(usize) -> Message + 'static, -) -> widget::Column<'static, Message, crate::Theme, Renderer> { +) -> widget::Column<'a, Message, crate::Theme, Renderer> { if open { - devices.iter().cloned().enumerate().fold( + devices.iter().enumerate().fold( column![revealer_head(open, title, selected, toggle)].width(Length::Fill), - |col, (id, name)| { + move |col, (id, name)| { col.push( - menu_button(text::body(name)) + text::body(name.as_ref()) + .apply(menu_button) .on_press(change(id)) .width(Length::Fill) .padding([8, 48]), @@ -785,9 +855,9 @@ fn revealer_head( selected: String, toggle: Message, ) -> cosmic::widget::Button<'static, Message> { - menu_button(column![ - text::body(title).width(Length::Fill), - text::caption(selected), - ]) - .on_press(toggle) + cosmic::widget::column::with_capacity(2) + .push(text::body(title).width(Length::Fill)) + .push(text::caption(selected)) + .apply(menu_button) + .on_press(toggle) } diff --git a/cosmic-applet-audio/src/model.rs b/cosmic-applet-audio/src/model.rs new file mode 100644 index 00000000..42c76b3c --- /dev/null +++ b/cosmic-applet-audio/src/model.rs @@ -0,0 +1,393 @@ +// 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 6ae8547a..38306e45 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::{self, Event}, + event::Event, layout, mouse, overlay, renderer, touch, widget::{Operation, Tree, tree}, }; From 456d0525357bfad0f9687b3c49cfbdc3c078a608 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 17 Jun 2026 20:56:08 -0400 Subject: [PATCH 12/37] improv(audio): adjust popup size based on window size --- cosmic-applet-audio/src/lib.rs | 112 +++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 39 deletions(-) diff --git a/cosmic-applet-audio/src/lib.rs b/cosmic-applet-audio/src/lib.rs index 3fd7b963..9bd585d9 100644 --- a/cosmic-applet-audio/src/lib.rs +++ b/cosmic-applet-audio/src/lib.rs @@ -19,13 +19,17 @@ use cosmic::{ cosmic_config::CosmicConfigEntry, cosmic_theme::Spacing, iced::{ - self, Alignment, Length, Subscription, + self, Alignment, Length, Rectangle, Subscription, futures::StreamExt, widget::{self, column, row, slider}, window, }, surface, theme, - widget::{Row, button, container, divider, icon, space, text, toggler}, + widget::{ + Row, button, container, divider, icon, + rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, + space, text, toggler, + }, }; use cosmic_settings_audio_client::{self as audio_client, CosmicAudioProxy}; use futures::SinkExt; @@ -73,6 +77,8 @@ 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 { @@ -138,6 +144,7 @@ pub enum Message { OpenSettings, Subscription(audio_client::Event), Surface(surface::Action), + Rectangle(RectangleUpdate), } // TODO @@ -272,6 +279,14 @@ 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::Ignore => {} Message::TogglePopup => { if let Some(p) = self.popup.take() { @@ -292,14 +307,21 @@ impl cosmic::Application for Audio { (100, &[][..]) }; - let popup_settings = self.core.applet.get_popup_settings( + let mut popup_settings = self.core.applet.get_popup_settings( self.core.main_window_id().unwrap(), new_id, None, None, None, ); - + if let Some(r) = self.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, + }; + } return get_popup(popup_settings); } } @@ -548,6 +570,7 @@ impl cosmic::Application for Audio { }, ) }), + rectangle_tracker_subscription(0).map(|update| Message::Rectangle(update.1)), ]) } @@ -573,48 +596,59 @@ impl cosmic::Application for Audio { 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()); - 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, - ), + 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, ), - 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() + ), + 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 } fn view_window(&self, _id: window::Id) -> Element<'_, Message> { From f97dc5a31e8c2040af5ebd5914f7db0cb215deb0 Mon Sep 17 00:00:00 2001 From: Ilia Malanin Date: Sat, 20 Jun 2026 02:07:18 +0200 Subject: [PATCH 13/37] fix(minimize): cache captured data for minimized toplevels --- cosmic-applet-minimize/src/wayland_handler.rs | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/cosmic-applet-minimize/src/wayland_handler.rs b/cosmic-applet-minimize/src/wayland_handler.rs index bf2eae30..562693e2 100644 --- a/cosmic-applet-minimize/src/wayland_handler.rs +++ b/cosmic-applet-minimize/src/wayland_handler.rs @@ -121,6 +121,7 @@ struct AppData { toplevel_info_state: ToplevelInfoState, toplevel_manager_state: ToplevelManagerState, seat_state: SeatState, + captured_toplevels: std::collections::HashSet, } struct CaptureData { @@ -351,6 +352,36 @@ 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 { @@ -364,23 +395,7 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - 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()), - ))); - } - } + self.handle_toplevel(toplevel, true); } fn update_toplevel( @@ -389,21 +404,7 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - 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()), - ))); - } - } + self.handle_toplevel(toplevel, false); } fn toplevel_closed( @@ -412,9 +413,7 @@ impl ToplevelInfoHandler for AppData { _qh: &QueueHandle, toplevel: &ExtForeignToplevelHandleV1, ) { - let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( - ToplevelUpdate::Remove(toplevel.clone()), - ))); + self.remove_toplevel(toplevel); } } @@ -482,6 +481,7 @@ 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 { From f022b6c1a905b6ab1f7a0a0b47fc6f3e32cc252b Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 23 Jun 2026 08:02:02 +0200 Subject: [PATCH 14/37] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: CYAXXX <85353920+CYAXXX@users.noreply.github.com> Co-authored-by: Hosted Weblate Co-authored-by: Hugo Carvalho Co-authored-by: Isaac Subirana Co-authored-by: Jun Hwi Ku Co-authored-by: Walter William Beckerleg Bruckman Co-authored-by: Yuya Furukuwa Co-authored-by: therealmate Co-authored-by: Димко Co-authored-by: 김유빈 Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-app-list/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-a11y/ja/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-a11y/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-audio/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-audio/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-battery/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-battery/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-bluetooth/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-bluetooth/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-network/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-network/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-notifications/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-notifications/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-power/ca/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-power/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-power/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-tiling/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-tiling/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applet-time/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/ja/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/ko/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/pt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-applets-desktop-entries/uk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-input-sources-applet/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-workspaces-applet/kmr/ Translation: Pop OS/COSMIC Accessibility Applet Translation: Pop OS/COSMIC App List Applet Translation: Pop OS/COSMIC Applets Desktop Entries Translation: Pop OS/COSMIC Audio Applet Translation: Pop OS/COSMIC Battery Applet Translation: Pop OS/COSMIC Bluetooth Applet Translation: Pop OS/COSMIC Input Sources Applet Translation: Pop OS/COSMIC Network Applet Translation: Pop OS/COSMIC Notifications Applet Translation: Pop OS/COSMIC Power Applet Translation: Pop OS/COSMIC Tiling Applet Translation: Pop OS/COSMIC Time Applet Translation: Pop OS/COSMIC Workspaces Applet --- cosmic-app-list/i18n/kmr/cosmic_app_list.ftl | 8 +++ .../i18n/ja/cosmic_applet_a11y.ftl | 2 +- .../i18n/kmr/cosmic_applet_a11y.ftl | 6 +++ .../i18n/kmr/cosmic_applet_audio.ftl | 7 +++ .../i18n/kmr/cosmic_applet_battery.ftl | 14 +++++ .../i18n/kmr/cosmic_applet_bluetooth.ftl | 12 +++++ .../i18n/kmr/cosmic_applet_input_sources.ftl | 2 + .../i18n/kmr/cosmic_applet_network.ftl | 24 +++++++++ .../i18n/kmr/cosmic_applet_notifications.ftl | 19 +++++++ .../i18n/kmr/cosmic_applet_power.ftl | 36 +++++++++++++ .../i18n/kmr/cosmic_applet_tiling.ftl | 20 ++++++++ .../i18n/kmr/cosmic_applet_time.ftl | 1 + .../i18n/kmr/cosmic_applet_workspaces.ftl | 1 + i18n/ja/desktop_entries.ftl | 1 + i18n/kmr/desktop_entries.ftl | 51 +++++++++++++++++++ i18n/ko/desktop_entries.ftl | 3 ++ i18n/pt/desktop_entries.ftl | 5 ++ 17 files changed, 211 insertions(+), 1 deletion(-) diff --git a/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl b/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl index e69de29b..793d1880 100644 --- a/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/kmr/cosmic_app_list.ftl @@ -0,0 +1,8 @@ +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-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl b/cosmic-applet-a11y/i18n/ja/cosmic_applet_a11y.ftl index 75249579..564e0d4f 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 e69de29b..4c772791 100644 --- a/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl +++ b/cosmic-applet-a11y/i18n/kmr/cosmic_applet_a11y.ftl @@ -0,0 +1,6 @@ +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-audio/i18n/kmr/cosmic_applet_audio.ftl b/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl index e69de29b..373ab157 100644 --- a/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl +++ b/cosmic-applet-audio/i18n/kmr/cosmic_applet_audio.ftl @@ -0,0 +1,7 @@ +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-battery/i18n/kmr/cosmic_applet_battery.ftl b/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl index e69de29b..8c0d92d1 100644 --- a/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl +++ b/cosmic-applet-battery/i18n/kmr/cosmic_applet_battery.ftl @@ -0,0 +1,14 @@ +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-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl b/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl index e69de29b..988f00ca 100644 --- a/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl +++ b/cosmic-applet-bluetooth/i18n/kmr/cosmic_applet_bluetooth.ftl @@ -0,0 +1,12 @@ +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-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl b/cosmic-applet-input-sources/i18n/kmr/cosmic_applet_input_sources.ftl index e69de29b..737324c5 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 @@ -0,0 +1,2 @@ +show-keyboard-layout = Awaya kilîtdankê nîşan bide... +keyboard-settings = Sazkariyên kilîtdankê... diff --git a/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl index e69de29b..3dbb0266 100644 --- a/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/kmr/cosmic_applet_network.ftl @@ -0,0 +1,24 @@ +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-notifications/i18n/kmr/cosmic_applet_notifications.ftl b/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl index e69de29b..b7a7578a 100644 --- a/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl +++ b/cosmic-applet-notifications/i18n/kmr/cosmic_applet_notifications.ftl @@ -0,0 +1,19 @@ +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-power/i18n/kmr/cosmic_applet_power.ftl b/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl index e69de29b..003f4a23 100644 --- a/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl +++ b/cosmic-applet-power/i18n/kmr/cosmic_applet_power.ftl @@ -0,0 +1,36 @@ +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-tiling/i18n/kmr/cosmic_applet_tiling.ftl b/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl index e69de29b..e3f124ff 100644 --- a/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl +++ b/cosmic-applet-tiling/i18n/kmr/cosmic_applet_tiling.ftl @@ -0,0 +1,20 @@ +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-time/i18n/kmr/cosmic_applet_time.ftl b/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl index e69de29b..e6ff41f9 100644 --- a/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl +++ b/cosmic-applet-time/i18n/kmr/cosmic_applet_time.ftl @@ -0,0 +1 @@ +datetime-settings = Sazkariyên dîrok, dem û salnameyê... diff --git a/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl b/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl index e69de29b..e262ce29 100644 --- a/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl +++ b/cosmic-applet-workspaces/i18n/kmr/cosmic_applet_workspaces.ftl @@ -0,0 +1 @@ +cosmic-applet-workspaces = Qadên xebatê yên COSMIC diff --git a/i18n/ja/desktop_entries.ftl b/i18n/ja/desktop_entries.ftl index e69de29b..c5b41c0a 100644 --- a/i18n/ja/desktop_entries.ftl +++ b/i18n/ja/desktop_entries.ftl @@ -0,0 +1 @@ +cosmic-applet-a11y = アクセシビリティ diff --git a/i18n/kmr/desktop_entries.ftl b/i18n/kmr/desktop_entries.ftl index e69de29b..0a42fc18 100644 --- a/i18n/kmr/desktop_entries.ftl +++ b/i18n/kmr/desktop_entries.ftl @@ -0,0 +1,51 @@ +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 7a9abf42..17b758c9 100644 --- a/i18n/ko/desktop_entries.ftl +++ b/i18n/ko/desktop_entries.ftl @@ -46,3 +46,6 @@ 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/pt/desktop_entries.ftl b/i18n/pt/desktop_entries.ftl index de93fad1..1fe912c3 100644 --- a/i18n/pt/desktop_entries.ftl +++ b/i18n/pt/desktop_entries.ftl @@ -20,3 +20,8 @@ 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; From 1473e1f008ab11c07cf1a63dbe10e98a9cc5d7fc Mon Sep 17 00:00:00 2001 From: LKramer Date: Thu, 25 Jun 2026 13:05:36 +0100 Subject: [PATCH 15/37] fix(network): register secret agent at NetworkManager's expected object path Co-authored-by: Claude Opus 4.8 (1M context) --- ....CosmicSettings.Applet.NetworkManager.SecretAgent.conf | 8 ++++++++ cosmic-applet-network/src/app.rs | 1 + justfile | 5 ++++- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf 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 new file mode 100644 index 00000000..8e98cedb --- /dev/null +++ b/cosmic-applet-network/data/dbus-1/system.d/com.system76.CosmicSettings.Applet.NetworkManager.SecretAgent.conf @@ -0,0 +1,8 @@ + + + + + + diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index a550859d..d5060834 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -405,6 +405,7 @@ fn secret_agent_task(identifier: String) -> 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; diff --git a/justfile b/justfile index 91f0958f..99c53104 100644 --- a/justfile +++ b/justfile @@ -59,8 +59,11 @@ _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: (_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 # Vendor Cargo dependencies locally vendor: From c2a00a36a80f1fdb75174a551daba9f1fc1e6eba Mon Sep 17 00:00:00 2001 From: Fred Date: Fri, 26 Jun 2026 18:30:06 +0200 Subject: [PATCH 16/37] feat(network): use libcosmic spinner for connecting states --- cosmic-applet-network/src/app.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index d5060834..0b6dbe24 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -35,7 +35,7 @@ use cosmic::{ widget::{ Id, button, column, container, divider, icon::{self, from_name}, - row, scrollable, secure_input, text, text_input, toggler, + indeterminate_circular, row, scrollable, secure_input, text, text_input, toggler, }, }; use cosmic_dbus_networkmanager::interface::enums::{ @@ -1516,12 +1516,7 @@ impl cosmic::Application for CosmicNetworkApplet { ]; match state { ActiveConnectionState::Activating | ActiveConnectionState::Deactivating => { - btn_content.push( - icon::from_name("process-working-symbolic") - .size(24) - .symbolic(true) - .into(), - ); + btn_content.push(indeterminate_circular().size(24.0).into()); } ActiveConnectionState::Activated => btn_content.push( text::body(fl!("connected")) @@ -1729,12 +1724,7 @@ impl cosmic::Application for CosmicNetworkApplet { .into(), ); btn_content.push(ssid.into()); - btn_content.push( - icon::from_name("process-working-symbolic") - .size(24) - .symbolic(true) - .into(), - ); + btn_content.push(indeterminate_circular().size(24.0).into()); } else if matches!(known.state, DeviceState::Unavailable) { btn_content.push( icon::from_name("network-wireless-disconnected-symbolic") @@ -1906,10 +1896,7 @@ impl cosmic::Application for CosmicNetworkApplet { let connecting = padded_control( row::with_children([ Element::from(id), - icon::from_name("process-working-symbolic") - .size(24) - .symbolic(true) - .into(), + indeterminate_circular().size(24.0).into(), ]) .spacing(8), ); From 1f7c59fb2ba78e839e46ea1e0c52426beb6c625d Mon Sep 17 00:00:00 2001 From: Fred Date: Fri, 26 Jun 2026 23:56:47 +0200 Subject: [PATCH 17/37] feat(bluetooth): use spinner widget from libcosmic for connecting and pairing states --- cosmic-applet-bluetooth/src/app.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index 2ca95ec5..e27af8ef 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -21,7 +21,7 @@ use cosmic::{ widget::{Column, column, container, row}, }, theme, - widget::{button, divider, icon, scrollable, text}, + widget::{button, divider, icon, indeterminate_circular, scrollable, text}, }; use futures::FutureExt; use std::{collections::HashMap, sync::LazyLock, time::Duration}; @@ -367,14 +367,12 @@ impl cosmic::Application for CosmicBluetoothApplet { ); } BluerDeviceStatus::Paired => {} - BluerDeviceStatus::Connecting | BluerDeviceStatus::Disconnecting => { - row = row.push( - icon::from_name("process-working-symbolic") - .size(24) - .symbolic(true), - ); + BluerDeviceStatus::Connecting + | BluerDeviceStatus::Disconnecting + | BluerDeviceStatus::Pairing => { + row = row.push(indeterminate_circular().size(24.0)); } - BluerDeviceStatus::Disconnected | BluerDeviceStatus::Pairing => continue, + BluerDeviceStatus::Disconnected => continue, } known_bluetooth.push( From 0441c67b1056cd1033b2d7fdbf139b47408edd1a Mon Sep 17 00:00:00 2001 From: William Fish Date: Mon, 29 Jun 2026 21:58:04 +0100 Subject: [PATCH 18/37] fix(battery): show plug icon without battery (#1432) --- cosmic-applet-battery/src/app.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index 9233a33f..c210d51a 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, sync::LazyLock, time::Duration}; +use std::{path::PathBuf, time::Duration}; use tokio::sync::mpsc::UnboundedSender; // XXX improve @@ -169,6 +169,20 @@ 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)] @@ -521,19 +535,9 @@ impl cosmic::Application for CosmicBatteryApplet { let applet_padding = self.core.applet.suggested_padding(true); let mut children = vec![ - 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(), + icon::from_name(self.panel_icon_name()) + .size(suggested_size.0) + .into(), ]; if self.config.show_percentage && !self.no_battery { From fddf3d569b5a68b8970038308ba066cee7414dde Mon Sep 17 00:00:00 2001 From: William Fish Date: Thu, 2 Jul 2026 17:02:40 +0100 Subject: [PATCH 19/37] fix(status-area): forward SNI scroll events (#1431) StatusNotifierItems can expose a Scroll(int delta, string orientation) method for tray hosts to call when the user wheels over an item. The status-area applet handled activation and context menus, but did not forward wheel events to that method. Track the hovered tray item only while the pointer is over an icon, ignore wheel events already captured by widgets, accumulate fine-grained wheel deltas into discrete scroll steps, and call Scroll on the item proxy. Add unit coverage for the delta/orientation mapping and pixel accumulation. Signed-off-by: William Fish --- .../src/components/app.rs | 114 ++++++++++++++++-- .../src/subscriptions/status_notifier_item.rs | 2 + 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/cosmic-applet-status-area/src/components/app.rs b/cosmic-applet-status-area/src/components/app.rs index 1071d7ac..3ad8c6ff 100644 --- a/cosmic-applet-status-area/src/components/app.rs +++ b/cosmic-applet-status-area/src/components/app.rs @@ -9,11 +9,14 @@ use cosmic::{ }, cctk::sctk::reexports::calloop, iced::{ - self, Length, Subscription, + self, + Event::Mouse, + Length, Subscription, event, + mouse::{self, ScrollDelta}, platform_specific::shell::commands::popup::{destroy_popup, get_popup}, - theme::Style, window, }, + scroll::{DiscreteScrollDelta, DiscreteScrollState}, surface, widget::{container, mouse_area}, }; @@ -33,7 +36,8 @@ pub enum Msg { StatusMenu((usize, status_menu::Msg)), StatusNotifier(status_notifier_watcher::Event), TogglePopup(usize), - Hovered(usize), + Hovered(Option), + WheelScrolled(ScrollDelta), Surface(surface::Action), ToggleOverflow, HoveredOverflow, @@ -49,6 +53,8 @@ pub(crate) struct App { max_menu_id: usize, popup: Option, overflow_popup: Option, + hovered_menu: Option, + scroll_states: BTreeMap, token_tx: Option>, } @@ -103,9 +109,10 @@ 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(*id)) + .on_enter(Msg::Hovered(Some(*id))) + .on_exit(Msg::Hovered(None)) .into() }); @@ -210,6 +217,7 @@ 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 { @@ -312,6 +320,10 @@ 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 { @@ -361,6 +373,19 @@ impl cosmic::Application for App { 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), @@ -405,6 +430,7 @@ impl cosmic::Application for App { } } 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 @@ -460,6 +486,12 @@ 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) } @@ -472,9 +504,10 @@ 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(*id)) + .on_enter(Msg::Hovered(Some(*id))) + .on_exit(Msg::Hovered(None)) .into() }); @@ -570,6 +603,33 @@ 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, @@ -614,3 +674,43 @@ 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/subscriptions/status_notifier_item.rs b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs index c03f0f54..2c3d4904 100644 --- a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs +++ b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs @@ -202,6 +202,8 @@ 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)] From d726dd890e0ff3530581766d35cd3824bcf1980d Mon Sep 17 00:00:00 2001 From: Ilia Malanin Date: Mon, 29 Jun 2026 12:30:30 +0200 Subject: [PATCH 20/37] fix(bluetooth): do not filter out already found devices --- cosmic-applet-bluetooth/src/bluetooth.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index cc3b693d..5184aa6a 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -855,13 +855,7 @@ async fn bluer_state(adapter: &Adapter) -> BluerState { #[inline(never)] async fn build_device_list(mut devices: Vec, adapter: &Adapter) -> Vec { - let addrs: Vec
= adapter - .device_addresses() - .await - .unwrap_or_default() - .into_iter() - .filter(|addr| !devices.iter().any(|d| d.address == *addr)) - .collect(); + let addrs = adapter.device_addresses().await.unwrap_or_default(); devices.clear(); if addrs.len() > devices.capacity() { From 1ce1d39ea3c493802fd2c0b571d84e55ec9b2e73 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 12:39:19 +0200 Subject: [PATCH 21/37] yoda: dock icon hover magnification (macOS Tahoe-style, phase B v1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First pass at the signature macOS Dock effect — the icon under the pointer grows, adjacent icons stay at base size. Full fisheye (smooth bell-curve scaling on neighbors) can be a later iteration. Changes in cosmic-app-list/src/app.rs: - CosmicAppList gains a hovered_dock_item: Option auto-initialized to None via #[derive(Default)]. - New Message::DockItemHover(Option) handled in update() by just writing the field; view() then reads it to decide scale. - DockItem::as_icon gains an icon_scale: f32 parameter. Inside it the cosmic_icon width/height = (base_icon_size * icon_scale) clamped to u16; indicator dot and other surrounding layout stay at base size so only the icon visually bulges. - New App::icon_scale_for(id) helper: 1.3 if Some(id) == hovered, 1.0 otherwise. Single place to tune the magnification factor. - The two main dock rows (favorites + filtered_active_list) wrap their rendered applet_tooltip in widget::mouse_area with on_enter(DockItemHover(Some(id))) / on_exit(DockItemHover(None)) and call icon_scale_for before rendering. - The three remaining as_icon call sites (DnD preview, favorites overflow popup, active overflow popup) pass icon_scale = 1.0 — hover magnification on those surfaces would look jittery and isn't needed anyway. Build: cargo build --release -p cosmic-app-list (≈ 7s). Binary installed at /usr/local/bin/cosmic-app-list, backup kept as .pre-magnification. --- cosmic-app-list/src/app.rs | 111 +++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 16 deletions(-) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index 932ffd6c..a6b967f7 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -187,6 +187,11 @@ 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, @@ -205,17 +210,35 @@ 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(app_icon.icon_size.into()) - .height(app_icon.icon_size.into()); + .width(scaled_icon_size.into()) + .height(scaled_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 { @@ -229,22 +252,34 @@ impl DockItem { } } .apply(container) - .padding(app_icon.dot_radius); + .padding(effective_radius); if toplevel_count == 0 { container } else { - container.class(theme::Container::custom(move |theme| container::Style { - background: if is_focused { - Some(Background::Color(theme.cosmic().accent_color().into())) + 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 } else { - Some(Background::Color(theme.cosmic().on_bg_color().into())) - }, - border: Border { - radius: dot_border_radius.into(), + on_bg + }; + + container::Style { + background: Some(Background::Color(fill)), + border: Border { + radius: dot_border_radius.into(), + ..Default::default() + }, ..Default::default() - }, - ..Default::default() + } })) } }; @@ -374,6 +409,9 @@ 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, overflow_favorites_popup: Option, overflow_active_popup: Option, } @@ -389,6 +427,9 @@ enum Message { Wayland(WaylandUpdate), PinApp(u32), UnpinApp(u32), + /// Yoda: pointer entered (Some) or left (None) a dock icon — drives + /// the macOS Tahoe-style hover magnification effect. + DockItemHover(Option), Popup(u32, window::Id), Pressed(window::Id), ToplevelListPopup(u32, window::Id), @@ -647,6 +688,17 @@ impl CosmicAppList { .collect::>(); } + /// Yoda: macOS-Tahoe-style hover magnification. Returns the icon + /// size multiplier for a given dock item — 1.3× when the pointer + /// is over it, 1.0× otherwise. Called from the view() icon builders. + fn icon_scale_for(&self, id: &DockItemId) -> f32 { + if self.hovered_dock_item.as_ref() == Some(id) { + 1.3 + } else { + 1.0 + } + } + fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool { use cosmic_app_list_config::ToplevelFilter; @@ -1582,6 +1634,9 @@ impl cosmic::Application for CosmicAppList { Message::GpuRequest(gpus) => { self.gpus = gpus; } + Message::DockItemHover(id) => { + self.hovered_dock_item = id; + } Message::OpenActive => { let create_new = self.overflow_active_popup.is_none(); let mut cmds = vec![self.close_popups()]; @@ -1763,7 +1818,9 @@ impl cosmic::Application for CosmicAppList { .filter(|(info, _)| self.is_on_current_monitor_and_workspace(info)) .any(|y| focused_item.contains(&y.0.foreign_toplevel)); - self.core + let dock_id = dock_item.id; + let icon_scale = self.icon_scale_for(&DockItemId::from(dock_id)); + let tooltip = self.core .applet .applet_tooltip::( dock_item.as_icon( @@ -1776,6 +1833,7 @@ 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 @@ -1785,7 +1843,10 @@ 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(); @@ -1836,6 +1897,10 @@ 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() { @@ -1875,8 +1940,10 @@ 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)); - self.core + let tooltip = self.core .applet .applet_tooltip( dock_item.as_icon( @@ -1889,6 +1956,7 @@ 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 @@ -1898,7 +1966,10 @@ 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(); @@ -2313,6 +2384,10 @@ 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 @@ -2421,6 +2496,10 @@ 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 From 6f88c6fea441347badf38ac206614127e939c966 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 13:13:52 +0200 Subject: [PATCH 22/37] yoda: fisheye magnification for dock hover (phase B v2 / c) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the binary 1.3× hover with a true gaussian bell curve — the hovered icon still peaks at ~1.35×, but the ±1 neighbours also bulge noticeably, ±2 a bit, and ±3+ relax to 1.0×. Footprint ~5 icons wide, matching the macOS Dock fisheye feel. Implementation in fn icon_scale_for(id): - Reads the hovered icon's and the current icon's bounds from self.rectangles (already populated by the existing RectangleTracker subscription — no new plumbing). - Distance = |this_center - hovered_center| along the panel's long axis (horizontal for Top/Bottom anchors, vertical for Left/Right). - sigma = hovered_extent * 1.4 so the bell's half-width matches one icon width (neighbors clearly pulled, far icons untouched). - scale = 1.0 + PEAK * exp(-(d/sigma)²) with PEAK = 0.35. - Falls back to binary 1.35×/1.0× when rectangle data isn't populated yet (first render / resize) — visibly responsive even before the tracker catches up. No widget signature changes vs v1, just a smarter formula. All five as_icon call sites already pass the result of icon_scale_for so this update propagates everywhere. Still on the TODO list: smooth animation (b). Right now icon→icon transitions snap instantly; a smoothed_hover_center + tick subscription would lerp it. Deferred to a follow-up commit. --- cosmic-app-list/src/app.rs | 59 ++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index a6b967f7..7fd4337f 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -688,15 +688,62 @@ impl CosmicAppList { .collect::>(); } - /// Yoda: macOS-Tahoe-style hover magnification. Returns the icon - /// size multiplier for a given dock item — 1.3× when the pointer - /// is over it, 1.0× otherwise. Called from the view() icon builders. + /// 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). fn icon_scale_for(&self, id: &DockItemId) -> f32 { - if self.hovered_dock_item.as_ref() == Some(id) { - 1.3 + 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; + + let Some(hovered_id) = self.hovered_dock_item.as_ref() else { + return 1.0; + }; + + // Without tracker data we can't compute distance — still peak on + // the hovered one so something visibly responds immediately. + let (Some(hovered_rect), Some(this_rect)) = + (self.rectangles.get(hovered_id), self.rectangles.get(id)) + else { + return if id == hovered_id { 1.0 + PEAK } else { 1.0 }; + }; + + let is_horizontal = matches!( + self.core.applet.anchor, + PanelAnchor::Top | PanelAnchor::Bottom + ); + let hovered_center = if is_horizontal { + hovered_rect.x + hovered_rect.width / 2.0 } else { - 1.0 + hovered_rect.y + hovered_rect.height / 2.0 + }; + let this_center = if is_horizontal { + this_rect.x + this_rect.width / 2.0 + } else { + this_rect.y + this_rect.height / 2.0 + }; + let distance = (this_center - hovered_center).abs(); + let icon_extent = if is_horizontal { + hovered_rect.width + } else { + hovered_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 * (-t * t).exp() } fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool { From d5c2a19e9542f9bd5ba832c202182b70c3c75aa6 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 14:15:43 +0200 Subject: [PATCH 23/37] yoda: smooth animated fisheye for dock hover (phase B v3, closes b) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inter-icon hover changes were snapping because icon_scale_for read the hovered icon's real rectangle directly. This adds a small animation layer so the bell center lerps toward the target and the whole effect fades in/out at the dock's edges. CosmicAppList gains three fields: - anim_hover_center: Option<(f32, f32)> — virtual cursor position, chases the hovered icon's center across ticks. - anim_hover_intensity: f32 (0..1) — global fade-in/out of the fisheye. Target 1.0 while a dock icon is hovered, 0.0 otherwise. - anim_last_tick: Option — for dt-based exponential smoothing (time-constant tau = 60ms, ~99% of target reached in ~120ms). A new Message::AnimTick(Instant) is emitted at ~60 fps by a conditional iced::time::every subscription — only active when the pointer is over a dock icon OR intensity hasn't faded back to ~0 yet, so the panel stays idle when no one is hovering the dock. icon_scale_for now reads anim_hover_center instead of rectangles[hovered] and multiplies the bell's peak by anim_hover_intensity. Behaviour: - Pointer slides A → B: bell glides continuously, both icons animate. - Pointer enters dock: icons inflate smoothly over ~120 ms. - Pointer leaves dock: icons deflate smoothly over ~120 ms. Fallback paths (first frame, missing rectangles) still respond instantly so the feature never looks 'stuck' before the animation kicks in. --- cosmic-app-list/src/app.rs | 120 ++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 16 deletions(-) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index 7fd4337f..d4d579a1 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -412,6 +412,18 @@ struct CosmicAppList { /// 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, } @@ -430,6 +442,10 @@ enum Message { /// 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), @@ -699,6 +715,10 @@ impl CosmicAppList { /// /// 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 — @@ -707,43 +727,54 @@ impl CosmicAppList { // close to 5 icons wide, Tahoe-ish). const SIGMA_FACTOR: f32 = 1.4; - let Some(hovered_id) = self.hovered_dock_item.as_ref() else { + // 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 + }; }; - // Without tracker data we can't compute distance — still peak on - // the hovered one so something visibly responds immediately. - let (Some(hovered_rect), Some(this_rect)) = - (self.rectangles.get(hovered_id), self.rectangles.get(id)) - else { - return if id == hovered_id { 1.0 + PEAK } 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 hovered_center = if is_horizontal { - hovered_rect.x + hovered_rect.width / 2.0 - } else { - hovered_rect.y + hovered_rect.height / 2.0 - }; let this_center = if is_horizontal { this_rect.x + this_rect.width / 2.0 } else { this_rect.y + this_rect.height / 2.0 }; - let distance = (this_center - hovered_center).abs(); + 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 { - hovered_rect.width + this_rect.width } else { - hovered_rect.height + 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 * (-t * t).exp() + 1.0 + PEAK * self.anim_hover_intensity * (-t * t).exp() } fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool { @@ -1683,6 +1714,49 @@ impl cosmic::Application for CosmicAppList { } 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(); @@ -2605,7 +2679,21 @@ 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( From c15a879c3168c04c758a6ae4d3d07f7f76545309 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Sun, 26 Apr 2026 11:10:19 +0200 Subject: [PATCH 24/37] fix(wayland): graceful exit on compositor disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace 3 panicking unwrap() in cosmic-app-list/wayland_handler.rs (event loop dispatch + 2 conn.flush in screencopy) with logged errors that break/return None instead. Wrap cosmic-applets/main.rs entry point in panic::catch_unwind to catch panics propagating from libcosmic/iced/winit (which we cannot patch locally without forking) when the COSMIC compositor closes the Wayland connection at logout. This eliminates the cascade of ~12 SIGABRT coredumps observed at session shutdown. Panic strategy is unwind (default), catch_unwind is sound here. Leyoda 2026 – GPLv3 --- cosmic-app-list/src/wayland_handler.rs | 15 +++++-- cosmic-applets/src/main.rs | 54 +++++++++++++++++--------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/cosmic-app-list/src/wayland_handler.rs b/cosmic-app-list/src/wayland_handler.rs index 03c16973..d27409dc 100644 --- a/cosmic-app-list/src/wayland_handler.rs +++ b/cosmic-app-list/src/wayland_handler.rs @@ -388,7 +388,10 @@ impl CaptureData { }, ) .unwrap(); - self.conn.flush().unwrap(); + if let Err(err) = self.conn.flush() { + tracing::error!("Wayland flush failed during screencopy session create: {err}"); + return None; + } let formats = session .wait_while(|data| data.formats.is_none()) @@ -437,7 +440,10 @@ impl CaptureData { session: capture_session.clone(), }, ); - self.conn.flush().unwrap(); + if let Err(err) = self.conn.flush() { + tracing::error!("Wayland flush failed during screencopy capture: {err}"); + return None; + } // TODO: wait for server to release buffer? let res = session @@ -709,7 +715,10 @@ pub(crate) fn wayland_handler( if app_data.exit { break; } - event_loop.dispatch(None, &mut app_data).unwrap(); + if let Err(err) = event_loop.dispatch(None, &mut app_data) { + tracing::error!("Wayland event loop terminated: {err}"); + break; + } } } diff --git a/cosmic-applets/src/main.rs b/cosmic-applets/src/main.rs index f62bbf21..dfd541d1 100644 --- a/cosmic-applets/src/main.rs +++ b/cosmic-applets/src/main.rs @@ -12,26 +12,44 @@ fn main() -> cosmic::iced::Result { }; let start = applet.rfind('/').map_or(0, |v| v + 1); - let cmd = &applet.as_str()[start..]; + let cmd = applet.as_str()[start..].to_string(); tracing::info!("Starting `{cmd}` with version {VERSION}"); - 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(()), + 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(()) + } } } From 66392fc42a316c8faac6dce959e05e6760caca0b Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Sun, 26 Apr 2026 11:12:15 +0200 Subject: [PATCH 25/37] chore: add redeploy.sh for /usr/local/bin install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds workspace release, backs up existing binaries, installs cosmic-applets/cosmic-app-list/cosmic-panel-button to /usr/local/bin (precedence over pacman package via $PATH). Leyoda 2026 – GPLv3 --- redeploy.sh | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100755 redeploy.sh diff --git a/redeploy.sh b/redeploy.sh new file mode 100755 index 00000000..7138a806 --- /dev/null +++ b/redeploy.sh @@ -0,0 +1,56 @@ +#!/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/Devels/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." From c117f172cbb966964bc9daab4312ad9c4f267b67 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Sun, 26 Apr 2026 14:51:33 +0200 Subject: [PATCH 26/37] fix(audio): accumuler les rafales scroll Pixels au lieu de signum() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avec Wayland axis_v120 (scroll haute-résolution sur souris HID modernes), un cran physique génère 5–8 events ScrollDelta::Pixels (~15–20px chacun). L'ancien code passait chaque sub-event par .signum() puis -1/+1 à sink_volume, donc un seul cran physique faisait varier le volume de 5 à 40% — résultat : scroll up sur l'icône audio panel / dock coupait le son si le volume était déjà bas. Fix : thread_local accumulator des deltas Pixels, émission seulement au passage du seuil de 15px par cran logique. Lines (souris classique sans axis_v120) reste proportionnel y * WHEEL_STEP. round() au lieu de truncation finale pour ne pas perdre les fractions de pourcent. Leyoda 2026 - GPLv3 --- cosmic-applet-audio/src/lib.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/cosmic-applet-audio/src/lib.rs b/cosmic-applet-audio/src/lib.rs index 9bd585d9..bd62dfbd 100644 --- a/cosmic-applet-audio/src/lib.rs +++ b/cosmic-applet-audio/src/lib.rs @@ -581,11 +581,31 @@ impl cosmic::Application for Audio { .icon_button(self.output_icon_name()) .on_press_down(Message::TogglePopup); - const WHEEL_STEP: f32 = 5.0; // 5% per wheel event + 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) }; + } let btn = crate::mouse_area::MouseArea::new(btn).on_mouse_wheel(|delta| { let scroll_vector = match delta { - iced::mouse::ScrollDelta::Lines { y, .. } => y.signum() * WHEEL_STEP, // -1/0/1 - iced::mouse::ScrollDelta::Pixels { y, .. } => y.signum(), // -1/0/1 + 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 + }) + } }; if scroll_vector == 0.0 { return Message::Ignore; @@ -593,7 +613,7 @@ impl cosmic::Application for Audio { let new_volume = (self.model.active_sink.volume as f64 + (scroll_vector as f64)) .clamp(0.0, self.max_sink_volume as f64); - Message::SetSinkVolume(new_volume as u32) + Message::SetSinkVolume(new_volume.round() as u32) }); let mut has_playback_buttons = false; From b4fbfe168a6714c63e161df3e415cc44b1dd6183 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 23 May 2026 20:49:24 +0200 Subject: [PATCH 27/37] chore: align applets with local stack --- Cargo.toml | 50 ++++++++++++++++--- cosmic-app-list/Cargo.toml | 2 +- .../cosmic-app-list-config/Cargo.toml | 2 +- cosmic-app-list/src/app.rs | 1 + cosmic-applet-a11y/Cargo.toml | 8 ++- cosmic-applet-a11y/src/app.rs | 4 +- cosmic-applet-a11y/src/backend/wayland/mod.rs | 5 +- cosmic-applet-audio/Cargo.toml | 4 +- cosmic-applet-battery/Cargo.toml | 8 ++- cosmic-applet-battery/src/app.rs | 3 +- cosmic-applet-bluetooth/Cargo.toml | 2 +- cosmic-applet-bluetooth/src/app.rs | 5 +- cosmic-applet-bluetooth/src/bluetooth.rs | 3 +- cosmic-applet-input-sources/Cargo.toml | 2 +- cosmic-applet-input-sources/src/lib.rs | 5 +- cosmic-applet-minimize/Cargo.toml | 2 +- cosmic-applet-minimize/src/lib.rs | 4 +- cosmic-applet-network/Cargo.toml | 5 +- cosmic-applet-notifications/Cargo.toml | 2 +- cosmic-applet-power/Cargo.toml | 2 +- cosmic-applet-power/src/lib.rs | 9 +--- cosmic-applet-status-area/Cargo.toml | 2 +- .../src/components/app.rs | 3 +- .../src/components/status_menu.rs | 2 +- .../src/status_notifier_watcher.rs | 9 ++-- cosmic-applet-tiling/Cargo.toml | 2 +- cosmic-applet-tiling/src/window.rs | 3 +- cosmic-applet-time/Cargo.toml | 2 +- cosmic-applet-time/src/window.rs | 5 +- cosmic-applet-workspaces/Cargo.toml | 2 +- .../src/components/app.rs | 1 + cosmic-applets/Cargo.toml | 2 +- cosmic-panel-button/Cargo.toml | 2 +- cosmic-panel-button/src/lib.rs | 2 +- rust-toolchain.toml | 2 +- 35 files changed, 96 insertions(+), 71 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f97b6b28..40471449 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,11 +25,11 @@ resolver = "3" [workspace.dependencies] anyhow = "1.0.102" -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "d0e95be" } +cctk = { package = "cosmic-client-toolkit", path = "../cosmic-protocols/client-toolkit" } cosmic-applets-config = { path = "cosmic-applets-config" } -cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [ +cosmic-protocols = { path = "../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" -libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = [ +cosmic = { package = "libcosmic-yoda", path = "../libcosmic", default-features = false, features = [ "applet", "applet-token", "dbus-config", @@ -58,7 +58,7 @@ 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 = { git = "https://github.com/pop-os/libcosmic" } +cosmic-config = { path = "../libcosmic/cosmic-config" } serde = { version = "1.0.228", features = ["derive"] } zlink = "0.5.0" @@ -82,12 +82,48 @@ ignored = ["libcosmic"] # winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" } # winit = { path = "../winit" } +[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/smithay/client-toolkit.git"] sctk = { package = "smithay-client-toolkit", version = "0.20.0" } [patch."https://github.com/pop-os/cosmic-protocols"] -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" } +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-network-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/network-manager" } +cosmic-settings-sound-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/sound" } +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" } +cosmic-settings-network-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/network-manager" } # [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 499d9f30..88c20a9a 100644 --- a/cosmic-app-list/Cargo.toml +++ b/cosmic-app-list/Cargo.toml @@ -13,7 +13,7 @@ futures.workspace = true i18n-embed.workspace = true i18n-embed-fl.workspace = true image = { version = "0.25.9", default-features = false } -libcosmic.workspace = true +cosmic.workspace = true memmap2 = "0.9.10" fastrand = "2.3.0" rust-embed.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 86b302ef..0d5a21d7 100644 --- a/cosmic-app-list/cosmic-app-list-config/Cargo.toml +++ b/cosmic-app-list/cosmic-app-list-config/Cargo.toml @@ -6,5 +6,5 @@ edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libcosmic.workspace = true +cosmic.workspace = true serde = { workspace = true, features = ["derive"] } diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index d4d579a1..bfb6b193 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -435,6 +435,7 @@ pub enum PopupType { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { Wayland(WaylandUpdate), PinApp(u32), diff --git a/cosmic-applet-a11y/Cargo.toml b/cosmic-applet-a11y/Cargo.toml index f7e3e50f..711b4ec6 100644 --- a/cosmic-applet-a11y/Cargo.toml +++ b/cosmic-applet-a11y/Cargo.toml @@ -9,7 +9,7 @@ cctk.workspace = true cosmic-protocols.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true rust-embed.workspace = true tokio.workspace = true tracing-log.workspace = true @@ -17,9 +17,7 @@ tracing-subscriber.workspace = true tracing.workspace = true [dependencies.cosmic-settings-a11y-manager-subscription] -git = "https://github.com/pop-os/cosmic-settings" -# path = "../../cosmic-settings/subscriptions/a11y-manager" +path = "../../cosmic-settings/subscriptions/a11y-manager" [dependencies.cosmic-settings-accessibility-subscription] -git = "https://github.com/pop-os/cosmic-settings" -# path = "../../cosmic-settings/subscriptions/accessibility" +path = "../../cosmic-settings/subscriptions/accessibility" diff --git a/cosmic-applet-a11y/src/app.rs b/cosmic-applet-a11y/src/app.rs index ad5f2a1e..6a328339 100644 --- a/cosmic-applet-a11y/src/app.rs +++ b/cosmic-applet-a11y/src/app.rs @@ -26,10 +26,9 @@ use cosmic::{ }; use cosmic_settings_a11y_manager_subscription::{ - self as cosmic_a11y_manager, AccessibilityEvent, AccessibilityRequest, ColorFilter, + 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 { @@ -52,6 +51,7 @@ struct CosmicA11yApplet { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), diff --git a/cosmic-applet-a11y/src/backend/wayland/mod.rs b/cosmic-applet-a11y/src/backend/wayland/mod.rs index fa9796f0..12340588 100644 --- a/cosmic-applet-a11y/src/backend/wayland/mod.rs +++ b/cosmic-applet-a11y/src/backend/wayland/mod.rs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only use anyhow; -use cctk::sctk::reexports::calloop::{self, channel::SyncSender}; +use cctk::sctk::reexports::calloop::{self}; use cosmic::iced::{ self, Subscription, - futures::{self, SinkExt, StreamExt, channel::mpsc}, + futures::{self, SinkExt}, 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 c47da57b..dae49747 100644 --- a/cosmic-applet-audio/Cargo.toml +++ b/cosmic-applet-audio/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0-only" futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true mpris2-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } rust-embed.workspace = true serde.workspace = true @@ -23,5 +23,5 @@ zlink.workspace = true intmap = "3.1.3" [dependencies.cosmic-settings-audio-client] -git = "https://github.com/pop-os/cosmic-settings-daemon" +path = "../../cosmic-settings-daemon/audio-client" features = ["codec"] diff --git a/cosmic-applet-battery/Cargo.toml b/cosmic-applet-battery/Cargo.toml index 8c8f6e1d..3310f8fa 100644 --- a/cosmic-applet-battery/Cargo.toml +++ b/cosmic-applet-battery/Cargo.toml @@ -12,7 +12,7 @@ drm = "0.14.1" futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true rust-embed.workspace = true rustc-hash.workspace = true tokio.workspace = true @@ -24,9 +24,7 @@ zbus.workspace = true serde.workspace = true [dependencies.cosmic-settings-upower-subscription] -git = "https://github.com/pop-os/cosmic-settings" -# path = "../../cosmic-settings/subscriptions/upower" +path = "../../cosmic-settings/subscriptions/upower" [dependencies.cosmic-settings-daemon-subscription] -git = "https://github.com/pop-os/cosmic-settings" -# path = "../../cosmic-settings/subscriptions/settings-daemon" +path = "../../cosmic-settings/subscriptions/settings-daemon" diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index c210d51a..22d9e6cc 100644 --- a/cosmic-applet-battery/src/app.rs +++ b/cosmic-applet-battery/src/app.rs @@ -186,6 +186,7 @@ impl CosmicBatteryApplet { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), @@ -525,7 +526,7 @@ impl cosmic::Application for CosmicBatteryApplet { Task::none() } - fn view(&self) -> Element { + fn view(&self) -> Element<'_, Message> { let is_horizontal = match self.core.applet.anchor { PanelAnchor::Top | PanelAnchor::Bottom => true, PanelAnchor::Left | PanelAnchor::Right => false, diff --git a/cosmic-applet-bluetooth/Cargo.toml b/cosmic-applet-bluetooth/Cargo.toml index e2108576..1ee209ee 100644 --- a/cosmic-applet-bluetooth/Cargo.toml +++ b/cosmic-applet-bluetooth/Cargo.toml @@ -10,7 +10,7 @@ bluer = { version = "0.17", features = ["bluetoothd", "id"] } futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true fastrand = "2.3.0" rust-embed.workspace = true rustc-hash.workspace = true diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index e27af8ef..484b8bf3 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -24,7 +24,7 @@ use cosmic::{ widget::{button, divider, icon, indeterminate_circular, scrollable, text}, }; use futures::FutureExt; -use std::{collections::HashMap, sync::LazyLock, time::Duration}; +use std::{collections::HashMap, time::Duration}; use tokio::sync::mpsc::Sender; use crate::{ @@ -63,6 +63,7 @@ impl CosmicBluetoothApplet { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { TogglePopup, CloseRequested(window::Id), @@ -145,7 +146,7 @@ impl cosmic::Application for CosmicBluetoothApplet { } Message::BluetoothEvent(e) => match e { BluerEvent::RequestResponse { - req, + req: _, state, err_msg, } => { diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index 5184aa6a..3a859932 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -149,8 +149,6 @@ pub fn bluetooth_subscription( }, BluerSessionEvent::AgentEvent(e) => BluerEvent::AgentEvent(e), - - _ => return, }; _ = output.send(message).await; @@ -199,6 +197,7 @@ pub enum BluerRequest { } #[derive(Debug, Clone)] +#[allow(dead_code)] pub enum BluerEvent { RequestResponse { req: BluerRequest, diff --git a/cosmic-applet-input-sources/Cargo.toml b/cosmic-applet-input-sources/Cargo.toml index 8fdb1dd9..6895d7fe 100644 --- a/cosmic-applet-input-sources/Cargo.toml +++ b/cosmic-applet-input-sources/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0-only" cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true rust-embed.workspace = true tokio.workspace = true tracing-log.workspace = true diff --git a/cosmic-applet-input-sources/src/lib.rs b/cosmic-applet-input-sources/src/lib.rs index 93e84283..2c845de1 100644 --- a/cosmic-applet-input-sources/src/lib.rs +++ b/cosmic-applet-input-sources/src/lib.rs @@ -3,7 +3,6 @@ mod localize; -use cosmic::iced::{Alignment, Length}; use cosmic::{ app, app::Core, @@ -14,16 +13,14 @@ use cosmic::{ iced::{ Rectangle, Task, platform_specific::shell::commands::popup::{destroy_popup, get_popup}, - widget::{column, row}, window::Id, }, - iced::{core::window, runtime::Appearance}, + iced::core::window, prelude::*, surface, theme, widget::{ self, autosize, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, - space, }, }; use cosmic_comp_config::CosmicCompConfig; diff --git a/cosmic-applet-minimize/Cargo.toml b/cosmic-applet-minimize/Cargo.toml index bd564bdf..29ee2c8e 100644 --- a/cosmic-applet-minimize/Cargo.toml +++ b/cosmic-applet-minimize/Cargo.toml @@ -9,7 +9,7 @@ anyhow.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true image = { version = "0.25.9", default-features = false } -libcosmic.workspace = true +cosmic.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 e40a7551..307762b5 100644 --- a/cosmic-applet-minimize/src/lib.rs +++ b/cosmic-applet-minimize/src/lib.rs @@ -316,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 @@ -420,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-network/Cargo.toml b/cosmic-applet-network/Cargo.toml index 3ba86f2b..4129a279 100644 --- a/cosmic-applet-network/Cargo.toml +++ b/cosmic-applet-network/Cargo.toml @@ -12,7 +12,7 @@ futures.workspace = true futures-util.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic = { workspace = true, features = [ +cosmic = { workspace = true, features = [ "applet", "applet-token", "tokio", @@ -34,5 +34,4 @@ nmrs = "3.1.3" [dependencies.cosmic-settings-network-manager-subscription] -git = "https://github.com/pop-os/cosmic-settings/" -# path = "../../cosmic-settings/subscriptions/network-manager" +path = "../../cosmic-settings/subscriptions/network-manager" diff --git a/cosmic-applet-notifications/Cargo.toml b/cosmic-applet-notifications/Cargo.toml index 2e472b24..91752579 100644 --- a/cosmic-applet-notifications/Cargo.toml +++ b/cosmic-applet-notifications/Cargo.toml @@ -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 -libcosmic.workspace = true +cosmic.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-power/Cargo.toml b/cosmic-applet-power/Cargo.toml index 693692e0..85f520f9 100644 --- a/cosmic-applet-power/Cargo.toml +++ b/cosmic-applet-power/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" [dependencies] i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true logind-zbus = "5.3.2" rust-embed.workspace = true rustix.workspace = true diff --git a/cosmic-applet-power/src/lib.rs b/cosmic-applet-power/src/lib.rs index 67725fbc..4a5829df 100644 --- a/cosmic-applet-power/src/lib.rs +++ b/cosmic-applet-power/src/lib.rs @@ -16,9 +16,8 @@ use cosmic::{ window, }, surface, theme, - widget::{Space, button, divider, icon, space, text}, + widget::{button, divider, icon, space, text}, }; -use std::sync::LazyLock; use logind_zbus::{ manager::ManagerProxy, @@ -35,9 +34,6 @@ 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(); @@ -49,7 +45,6 @@ struct Power { icon_name: String, popup: Option, token_tx: Option>, - subsurface_id: window::Id, } #[derive(Debug, Clone, Copy)] @@ -75,6 +70,7 @@ impl PowerAction { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { Action(PowerAction), TogglePopup, @@ -104,7 +100,6 @@ 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(), }, diff --git a/cosmic-applet-status-area/Cargo.toml b/cosmic-applet-status-area/Cargo.toml index d643f70d..d96913ab 100644 --- a/cosmic-applet-status-area/Cargo.toml +++ b/cosmic-applet-status-area/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0-only" [dependencies] futures.workspace = true -libcosmic.workspace = true +cosmic.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 3ad8c6ff..081dfe06 100644 --- a/cosmic-applet-status-area/src/components/app.rs +++ b/cosmic-applet-status-area/src/components/app.rs @@ -28,6 +28,7 @@ use crate::{ }; #[derive(Clone, Debug)] +#[allow(dead_code)] pub enum Msg { None, Activate(usize), @@ -637,7 +638,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; diff --git a/cosmic-applet-status-area/src/components/status_menu.rs b/cosmic-applet-status-area/src/components/status_menu.rs index e706f37b..6aa0953c 100644 --- a/cosmic-applet-status-area/src/components/status_menu.rs +++ b/cosmic-applet-status-area/src/components/status_menu.rs @@ -8,7 +8,7 @@ use cosmic::{ iced, widget::icon::{self, IconFallback}, }; -use std::path::{Path, PathBuf}; +use std::path::Path; use crate::subscriptions::status_notifier_item::{IconUpdate, Layout, StatusNotifierItem}; diff --git a/cosmic-applet-status-area/src/status_notifier_watcher.rs b/cosmic-applet-status-area/src/status_notifier_watcher.rs index 1bb75d79..5c8b6175 100644 --- a/cosmic-applet-status-area/src/status_notifier_watcher.rs +++ b/cosmic-applet-status-area/src/status_notifier_watcher.rs @@ -10,21 +10,18 @@ //! can be socket-activated and not conflict with anything else running as a status notifier //! watcher. //! -//! The daemon runs as long as as there is at least one client still connected. Which it checks -//! for every `REFRESH_INTERVAL`. +//! The daemon runs as long as there is at least one client still connected. use crate::subscriptions::status_notifier_watcher::server::create_service; use crate::unique_names::UniqueNames; use futures::StreamExt; -use std::{collections::HashSet, time::Duration}; +use std::collections::HashSet; 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() { @@ -42,7 +39,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-tiling/Cargo.toml b/cosmic-applet-tiling/Cargo.toml index 2ce1c452..2c245ddf 100644 --- a/cosmic-applet-tiling/Cargo.toml +++ b/cosmic-applet-tiling/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" license = "GPL-3.0-only" [dependencies] -libcosmic.workspace = true +cosmic.workspace = true anyhow.workspace = true cctk.workspace = true cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } diff --git a/cosmic-applet-tiling/src/window.rs b/cosmic-applet-tiling/src/window.rs index 327d5d75..7da430e3 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, time::Instant}; +use std::thread; use tracing::error; const ID: &str = "com.system76.CosmicAppletTiling"; @@ -46,6 +46,7 @@ pub struct Window { } #[derive(Clone, Debug)] +#[allow(dead_code)] pub enum Message { TogglePopup, PopupClosed(Id), diff --git a/cosmic-applet-time/Cargo.toml b/cosmic-applet-time/Cargo.toml index a6ca4dfd..a8713231 100644 --- a/cosmic-applet-time/Cargo.toml +++ b/cosmic-applet-time/Cargo.toml @@ -9,7 +9,7 @@ cosmic-applets-config.workspace = true jiff = "0.2" i18n-embed-fl.workspace = true i18n-embed.workspace = true -libcosmic.workspace = true +cosmic.workspace = true rust-embed.workspace = true tokio.workspace = true tracing-log.workspace = true diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index a44d81ee..ddd37d31 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -94,6 +94,7 @@ pub struct Window { } #[derive(Debug, Clone)] +#[allow(dead_code)] pub enum Message { TogglePopup, CloseRequested(window::Id), @@ -361,7 +362,7 @@ impl cosmic::Application for Window { } fn subscription(&self) -> Subscription { - fn time_subscription(mut show_seconds: watch::Receiver) -> Subscription { + fn time_subscription(show_seconds: watch::Receiver) -> Subscription { struct Wrapper { inner: watch::Receiver, id: &'static str, @@ -376,7 +377,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 diff --git a/cosmic-applet-workspaces/Cargo.toml b/cosmic-applet-workspaces/Cargo.toml index 857b668d..103680e2 100644 --- a/cosmic-applet-workspaces/Cargo.toml +++ b/cosmic-applet-workspaces/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" license = "GPL-3.0-only" [dependencies] -libcosmic.workspace = true +cosmic.workspace = true cctk.workspace = true tracing.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-applet-workspaces/src/components/app.rs b/cosmic-applet-workspaces/src/components/app.rs index dc4ccdc4..a9bafb79 100644 --- a/cosmic-applet-workspaces/src/components/app.rs +++ b/cosmic-applet-workspaces/src/components/app.rs @@ -84,6 +84,7 @@ impl IcedWorkspacesApplet { } #[derive(Debug, Clone)] +#[allow(dead_code)] enum Message { WorkspaceUpdate(WorkspacesUpdate), WorkspacePressed(ExtWorkspaceHandleV1), diff --git a/cosmic-applets/Cargo.toml b/cosmic-applets/Cargo.toml index c2129dff..f204a80c 100644 --- a/cosmic-applets/Cargo.toml +++ b/cosmic-applets/Cargo.toml @@ -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" } -libcosmic.workspace = true +cosmic.workspace = true tracing.workspace = true tracing-subscriber.workspace = true tracing-log.workspace = true diff --git a/cosmic-panel-button/Cargo.toml b/cosmic-panel-button/Cargo.toml index 9fa73486..69074433 100644 --- a/cosmic-panel-button/Cargo.toml +++ b/cosmic-panel-button/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" license = "GPL-3.0-only" [dependencies] -libcosmic.workspace = true +cosmic.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 45ee1ca2..132e5dd5 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) = diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 79d20990..075062e5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.93" +channel = "1.93.0" From 0023a462ba1f3761c958bed7b8eb0096a24932dd Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 09:55:11 +0200 Subject: [PATCH 28/37] yoda: use local dbus settings bindings --- cosmic-app-list/Cargo.toml | 2 +- cosmic-applet-audio/Cargo.toml | 2 +- cosmic-applet-network/Cargo.toml | 2 +- cosmic-applet-time/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cosmic-app-list/Cargo.toml b/cosmic-app-list/Cargo.toml index 88c20a9a..b3171a2c 100644 --- a/cosmic-app-list/Cargo.toml +++ b/cosmic-app-list/Cargo.toml @@ -19,7 +19,7 @@ fastrand = "2.3.0" rust-embed.workspace = true rustix.workspace = true rustc-hash.workspace = true -switcheroo-control = { git = "https://github.com/pop-os/dbus-settings-bindings" } +switcheroo-control = { path = "../../dbus-settings-bindings/switcheroo-control" } tokio.workspace = true tracing-log.workspace = true tracing-subscriber.workspace = true diff --git a/cosmic-applet-audio/Cargo.toml b/cosmic-applet-audio/Cargo.toml index dae49747..3e67d3f5 100644 --- a/cosmic-applet-audio/Cargo.toml +++ b/cosmic-applet-audio/Cargo.toml @@ -9,7 +9,7 @@ futures.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true cosmic.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 diff --git a/cosmic-applet-network/Cargo.toml b/cosmic-applet-network/Cargo.toml index 4129a279..62efbaf9 100644 --- a/cosmic-applet-network/Cargo.toml +++ b/cosmic-applet-network/Cargo.toml @@ -7,7 +7,7 @@ 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" } +cosmic-dbus-networkmanager = { path = "../../dbus-settings-bindings/networkmanager" } futures.workspace = true futures-util.workspace = true i18n-embed-fl.workspace = true diff --git a/cosmic-applet-time/Cargo.toml b/cosmic-applet-time/Cargo.toml index a8713231..3c85ee07 100644 --- a/cosmic-applet-time/Cargo.toml +++ b/cosmic-applet-time/Cargo.toml @@ -17,5 +17,5 @@ tracing-subscriber.workspace = true tracing.workspace = true icu = { version = "2.1.1", features = ["compiled_data"] } zbus.workspace = true -timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } +timedate-zbus = { path = "../../dbus-settings-bindings/timedate" } logind-zbus = "5.3.2" From ebfaa4eb7b34e5b4d1969a84db83c0e4e1652fa2 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 11:34:55 +0200 Subject: [PATCH 29/37] chore: use local cosmic-text checkout --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 40471449..178a102c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,6 +125,9 @@ cosmic-settings-upower-subscription = { path = "/home/lionel/Projets/COSMIC/cosm cosmic-settings-airplane-mode-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/airplane-mode" } cosmic-settings-network-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/network-manager" } +[patch."https://github.com/pop-os/cosmic-text.git"] +cosmic-text = { path = "../cosmic-text" } + # [patch.'https://github.com/pop-os/dbus-settings-bindings'] # cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" } # upower_dbus = { path = "../dbus-settings-bindings/upower" } From 3c360142aeae3f585377ecc7f75d738916edce6e Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 18:10:22 +0200 Subject: [PATCH 30/37] chore: use local COSMIC support crates --- Cargo.lock | 7 +++---- Cargo.toml | 1 + cosmic-applet-input-sources/Cargo.toml | 2 +- cosmic-applet-tiling/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdd37740..96c26cd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,8 +1320,7 @@ dependencies = [ [[package]] name = "cosmic-comp-config" -version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-comp.git?rev=5eb5af4#5eb5af46756f2f2bc5e812cf68fe4c4b79efd924" +version = "1.0.0" dependencies = [ "cosmic-config", "input", @@ -3708,9 +3707,9 @@ dependencies = [ [[package]] name = "input" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdc09524a91f9cacd26f16734ff63d7dc650daffadd2b6f84d17a285bd875a9" +checksum = "f9793345a65d71317763a33066b5d8351f8760dde8d4930fe9e39b5f14a7959d" dependencies = [ "bitflags 2.11.1", "input-sys", diff --git a/Cargo.toml b/Cargo.toml index 178a102c..6f673cc2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ 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" diff --git a/cosmic-applet-input-sources/Cargo.toml b/cosmic-applet-input-sources/Cargo.toml index 6895d7fe..45b54857 100644 --- a/cosmic-applet-input-sources/Cargo.toml +++ b/cosmic-applet-input-sources/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" license = "GPL-3.0-only" [dependencies] -cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } +cosmic-comp-config.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true cosmic.workspace = true diff --git a/cosmic-applet-tiling/Cargo.toml b/cosmic-applet-tiling/Cargo.toml index 2c245ddf..7767a997 100644 --- a/cosmic-applet-tiling/Cargo.toml +++ b/cosmic-applet-tiling/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0-only" cosmic.workspace = true anyhow.workspace = true cctk.workspace = true -cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" } +cosmic-comp-config.workspace = true cosmic-protocols.workspace = true i18n-embed-fl.workspace = true i18n-embed.workspace = true From 9677159db6b3f140e370f3277d2cca4822f0fa43 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Tue, 26 May 2026 09:24:55 +0200 Subject: [PATCH 31/37] chore: fix applets redeploy path --- redeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redeploy.sh b/redeploy.sh index 7138a806..686bf3cb 100755 --- a/redeploy.sh +++ b/redeploy.sh @@ -11,7 +11,7 @@ set -euo pipefail -REPO="/home/lionel/Devels/cosmic-applets" +REPO="/home/lionel/Projets/COSMIC/cosmic-applets" TARGETS=( "cosmic-applets" "cosmic-app-list" From d58fe9d74cb62c6b7df9bccf5d1f10f05ae4d4d4 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Tue, 26 May 2026 10:39:01 +0200 Subject: [PATCH 32/37] feat: add editable dock launchers --- cosmic-app-list/i18n/en/cosmic_app_list.ftl | 8 +- cosmic-app-list/i18n/fr/cosmic_app_list.ftl | 6 + cosmic-app-list/src/app.rs | 378 ++++++++++++++++++-- cosmic-app-list/src/launcher_edit.rs | 378 ++++++++++++++++++++ cosmic-app-list/src/lib.rs | 1 + 5 files changed, 735 insertions(+), 36 deletions(-) create mode 100644 cosmic-app-list/src/launcher_edit.rs diff --git a/cosmic-app-list/i18n/en/cosmic_app_list.ftl b/cosmic-app-list/i18n/en/cosmic_app_list.ftl index c412cd51..066360b3 100644 --- a/cosmic-app-list/i18n/en/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/en/cosmic_app_list.ftl @@ -5,4 +5,10 @@ quit-all = Quit All new-window = New Window run = Run run-on = Run on {$gpu} -run-on-default = (Default) \ No newline at end of file +run-on-default = (Default) +edit-launcher = Edit launcher +launcher-name = Name +launcher-command = Command +launcher-icon = Icon +save = Save +cancel = Cancel diff --git a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl index 39cac491..f01fdf79 100644 --- a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl @@ -6,3 +6,9 @@ new-window = Nouvelle fenêtre run = Exécuter 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 +save = Enregistrer +cancel = Annuler diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index bfb6b193..e4f839f5 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -3,6 +3,7 @@ use crate::{ fl, + launcher_edit::{self, LauncherEditRequest}, wayland_subscription::{ OutputUpdate, ToplevelRequest, ToplevelUpdate, WaylandImage, WaylandRequest, WaylandUpdate, wayland_subscription, @@ -47,7 +48,7 @@ use cosmic::{ icon::{self, from_name}, image::Handle, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, - svg, text, + svg, text, text_input, }, }; use cosmic::{ @@ -387,10 +388,25 @@ 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, +} + #[derive(Clone, Default)] struct CosmicAppList { core: cosmic::app::Core, popup: Option, + launcher_edit: Option, subscription_ctr: u32, item_ctr: u32, desktop_entries: Vec, @@ -432,6 +448,7 @@ struct CosmicAppList { pub enum PopupType { RightClickMenu, ToplevelList, + LauncherEditor, } #[derive(Debug, Clone)] @@ -440,6 +457,13 @@ enum Message { Wayland(WaylandUpdate), PinApp(u32), UnpinApp(u32), + EditLauncher(u32), + LauncherNameChanged(String), + LauncherExecChanged(String), + LauncherIconChanged(String), + SaveLauncherEdit, + CancelLauncherEdit, + LauncherEditSaved(Result), /// Yoda: pointer entered (Some) or left (None) a dock icon — drives /// the macOS Tahoe-style hover magnification effect. DockItemHover(Option), @@ -822,10 +846,45 @@ 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() { @@ -1199,6 +1258,182 @@ 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.take() else { + return Task::none(); + }; + let Some(rectangle) = self.rectangles.get(&dock_item.id.into()) else { + self.popup = Some(existing_popup); + 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(); + + 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: dock_item + .desktop_info + .icon() + .unwrap_or_default() + .to_string(), + terminal: dock_item.desktop_info.terminal(), + saving: false, + error: None, + }); + + let new_id = window::Id::unique(); + let mut popup_settings = self.core.applet.get_popup_settings( + existing_popup.parent, + 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.positioner.size_limits = Limits::NONE + .min_width(480.) + .min_height(1.) + .max_width(520.) + .max_height(1000.); + + self.popup = Some(Popup { + parent: existing_popup.parent, + id: new_id, + dock_item, + popup_type: PopupType::LauncherEditor, + }); + + return Task::batch([destroy_popup(existing_popup.id), get_popup(popup_settings)]); + } + 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::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))); @@ -1651,6 +1886,9 @@ 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); } } @@ -1665,42 +1903,16 @@ impl cosmic::Application for CosmicAppList { } Message::ConfigUpdated(config) => { self.config = 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(); + self.update_desktop_entries(); + self.sync_pinned_list_from_config(); } Message::CloseRequested(id) => { - if Some(id) == self.popup.as_ref().map(|p| p.id) { + if let Some(popup) = &self.popup + && popup.id == id + { + if popup.popup_type == PopupType::LauncherEditor { + self.launcher_edit = None; + } self.popup = None; } if self.overflow_active_popup.is_some_and(|p| p == id) { @@ -2372,6 +2584,19 @@ 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() { @@ -2418,6 +2643,89 @@ 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), + text_input("", edit.icon.as_str()) + .label(fl!("launcher-icon")) + .on_input(Message::LauncherIconChanged) + .on_submit(|_| Message::SaveLauncherEdit) + .width(Length::Fill) + .size(14), + ] + .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 = diff --git a/cosmic-app-list/src/launcher_edit.rs b/cosmic-app-list/src/launcher_edit.rs new file mode 100644 index 00000000..c354e1e6 --- /dev/null +++ b/cosmic-app-list/src/launcher_edit.rs @@ -0,0 +1,378 @@ +// 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 51079cc4..56500b97 100644 --- a/cosmic-app-list/src/lib.rs +++ b/cosmic-app-list/src/lib.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only mod app; +mod launcher_edit; mod localize; mod wayland_handler; mod wayland_subscription; From 8d56d0b500e4ca66916498fd86586ce93707e037 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Tue, 26 May 2026 11:49:46 +0200 Subject: [PATCH 33/37] fix: open launcher editor in existing popup --- cosmic-app-list/src/app.rs | 42 +++----------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index e4f839f5..30936195 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -1265,11 +1265,7 @@ impl cosmic::Application for CosmicAppList { let Some(exec) = dock_item.desktop_info.exec() else { return Task::none(); }; - let Some(existing_popup) = self.popup.take() else { - return Task::none(); - }; - let Some(rectangle) = self.rectangles.get(&dock_item.id.into()) else { - self.popup = Some(existing_popup); + let Some(existing_popup) = self.popup.as_mut() else { return Task::none(); }; @@ -1303,40 +1299,8 @@ impl cosmic::Application for CosmicAppList { error: None, }); - let new_id = window::Id::unique(); - let mut popup_settings = self.core.applet.get_popup_settings( - existing_popup.parent, - 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.positioner.size_limits = Limits::NONE - .min_width(480.) - .min_height(1.) - .max_width(520.) - .max_height(1000.); - - self.popup = Some(Popup { - parent: existing_popup.parent, - id: new_id, - dock_item, - popup_type: PopupType::LauncherEditor, - }); - - return Task::batch([destroy_popup(existing_popup.id), get_popup(popup_settings)]); + existing_popup.dock_item = dock_item; + existing_popup.popup_type = PopupType::LauncherEditor; } Message::LauncherNameChanged(name) => { if let Some(edit) = self.launcher_edit.as_mut() From 04acc50e4d5c756798f0b3255deff583987b446c Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Tue, 26 May 2026 12:03:59 +0200 Subject: [PATCH 34/37] feat: add themed launcher icon catalog --- cosmic-app-list/i18n/en/cosmic_app_list.ftl | 5 + cosmic-app-list/i18n/fr/cosmic_app_list.ftl | 5 + cosmic-app-list/src/app.rs | 228 +++++++++- cosmic-app-list/src/icon_catalog.rs | 440 ++++++++++++++++++++ cosmic-app-list/src/lib.rs | 1 + 5 files changed, 665 insertions(+), 14 deletions(-) create mode 100644 cosmic-app-list/src/icon_catalog.rs diff --git a/cosmic-app-list/i18n/en/cosmic_app_list.ftl b/cosmic-app-list/i18n/en/cosmic_app_list.ftl index 066360b3..028a1558 100644 --- a/cosmic-app-list/i18n/en/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/en/cosmic_app_list.ftl @@ -10,5 +10,10 @@ 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 diff --git a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl index f01fdf79..16bb7465 100644 --- a/cosmic-app-list/i18n/fr/cosmic_app_list.ftl +++ b/cosmic-app-list/i18n/fr/cosmic_app_list.ftl @@ -10,5 +10,10 @@ 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/src/app.rs b/cosmic-app-list/src/app.rs index 30936195..59e8ed83 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - fl, + fl, icon_catalog, launcher_edit::{self, LauncherEditRequest}, wayland_subscription::{ OutputUpdate, ToplevelRequest, ToplevelUpdate, WaylandImage, WaylandRequest, WaylandUpdate, @@ -44,11 +44,11 @@ use cosmic::{ surface, theme::{self, Button, Container}, widget::{ - DndDestination, Image, button, container, divider, dnd_source, + DndDestination, Image, button, container, divider, dnd_source, grid, icon::{self, from_name}, image::Handle, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, - svg, text, text_input, + scrollable, svg, text, text_input, }, }; use cosmic::{ @@ -65,6 +65,8 @@ 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::(()) @@ -400,6 +402,16 @@ struct LauncherEditState { 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)] @@ -461,6 +473,10 @@ enum Message { LauncherNameChanged(String), LauncherExecChanged(String), LauncherIconChanged(String), + LauncherIconSearchChanged(String), + LauncherIconSelected(String), + ReloadLauncherIconCatalog, + LauncherIconCatalogLoaded(icon_catalog::IconCatalog), SaveLauncherEdit, CancelLauncherEdit, LauncherEditSaved(Result), @@ -708,6 +724,143 @@ 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], @@ -1281,6 +1434,12 @@ impl cosmic::Application for CosmicAppList { }) .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(), @@ -1289,18 +1448,26 @@ impl cosmic::Application for CosmicAppList { original_exec: original_exec.clone(), name: original_name, exec: original_exec, - icon: dock_item - .desktop_info - .icon() - .unwrap_or_default() - .to_string(), + 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() @@ -1326,6 +1493,44 @@ impl cosmic::Application for CosmicAppList { 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(); @@ -2633,12 +2838,7 @@ impl cosmic::Application for CosmicAppList { .on_submit(|_| Message::SaveLauncherEdit) .width(Length::Fill) .size(14), - text_input("", edit.icon.as_str()) - .label(fl!("launcher-icon")) - .on_input(Message::LauncherIconChanged) - .on_submit(|_| Message::SaveLauncherEdit) - .width(Length::Fill) - .size(14), + launcher_icon_editor(edit), ] .spacing(spacing.space_s) .width(Length::Fill); diff --git a/cosmic-app-list/src/icon_catalog.rs b/cosmic-app-list/src/icon_catalog.rs new file mode 100644 index 00000000..2cb05e1a --- /dev/null +++ b/cosmic-app-list/src/icon_catalog.rs @@ -0,0 +1,440 @@ +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/lib.rs b/cosmic-app-list/src/lib.rs index 56500b97..f6893335 100644 --- a/cosmic-app-list/src/lib.rs +++ b/cosmic-app-list/src/lib.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only mod app; +mod icon_catalog; mod launcher_edit; mod localize; mod wayland_handler; From ced6eb267ecee29b0f279f4e165b61b1ea909ca9 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Wed, 27 May 2026 08:48:24 +0200 Subject: [PATCH 35/37] Fix status menu build after upstream rebase --- cosmic-applet-status-area/src/components/status_menu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmic-applet-status-area/src/components/status_menu.rs b/cosmic-applet-status-area/src/components/status_menu.rs index 6aa0953c..e706f37b 100644 --- a/cosmic-applet-status-area/src/components/status_menu.rs +++ b/cosmic-applet-status-area/src/components/status_menu.rs @@ -8,7 +8,7 @@ use cosmic::{ iced, widget::icon::{self, IconFallback}, }; -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::subscriptions::status_notifier_item::{IconUpdate, Layout, StatusNotifierItem}; From adc97dc8f160804c9cd79930259606adb8146acb Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Thu, 2 Jul 2026 19:28:24 +0200 Subject: [PATCH 36/37] fix: adapt to cosmic-theme background(transparent) accessor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leyoda 2026 – GPLv3 --- cosmic-app-list/src/app.rs | 2 +- cosmic-applet-status-area/src/components/app.rs | 2 +- cosmic-panel-button/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index 59e8ed83..55d815b8 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -2787,7 +2787,7 @@ impl cosmic::Application for CosmicAppList { //TODO: move style to libcosmic .class(theme::Container::custom(|theme| { let cosmic = theme.cosmic(); - let component = &cosmic.background.component; + let component = &cosmic.background(false).component; container::Style { icon_color: Some(component.on.into()), text_color: Some(component.on.into()), diff --git a/cosmic-applet-status-area/src/components/app.rs b/cosmic-applet-status-area/src/components/app.rs index 081dfe06..7bedc653 100644 --- a/cosmic-applet-status-area/src/components/app.rs +++ b/cosmic-applet-status-area/src/components/app.rs @@ -656,7 +656,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.on.into()), + color: Some(theme.cosmic().background(false).on.into()), } })) } else { diff --git a/cosmic-panel-button/src/lib.rs b/cosmic-panel-button/src/lib.rs index 132e5dd5..5c875719 100644 --- a/cosmic-panel-button/src/lib.rs +++ b/cosmic-panel-button/src/lib.rs @@ -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.on.into()), + color: Some(theme.cosmic().background(false).on.into()), } })) } else { From ebecfa6b7da03c1f592fb257d0b79843bfb2edba Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 4 Jul 2026 11:20:22 +0200 Subject: [PATCH 37/37] chore: refresh lockfile post-upstream rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leyoda 2026 – GPLv3 --- Cargo.lock | 328 ++++++++++++----------------------------------------- 1 file changed, 75 insertions(+), 253 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96c26cd9..5ca8bed1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,12 +234,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" 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" version = "0.38.0+1.3.281" @@ -814,7 +808,6 @@ 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", @@ -824,22 +817,12 @@ 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" @@ -995,7 +978,7 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "image", - "libcosmic", + "libcosmic-yoda", "memmap2 0.9.10", "rust-embed", "rustc-hash 2.1.2", @@ -1013,7 +996,7 @@ dependencies = [ name = "cosmic-app-list-config" version = "1.0.15" dependencies = [ - "libcosmic", + "libcosmic-yoda", "serde", ] @@ -1028,7 +1011,7 @@ dependencies = [ "cosmic-settings-accessibility-subscription", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "tokio", "tracing", @@ -1045,7 +1028,7 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "intmap", - "libcosmic", + "libcosmic-yoda", "mpris2-zbus", "rust-embed", "serde", @@ -1068,11 +1051,11 @@ dependencies = [ "cosmic-config", "cosmic-settings-daemon-subscription", "cosmic-settings-upower-subscription", - "drm 0.14.1", + "drm", "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "rustc-hash 2.1.2", "serde", @@ -1094,7 +1077,7 @@ dependencies = [ "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "rustc-hash 2.1.2", "tokio", @@ -1110,7 +1093,7 @@ dependencies = [ "cosmic-comp-config", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "tokio", "tracing", @@ -1127,7 +1110,7 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "image", - "libcosmic", + "libcosmic-yoda", "memmap2 0.9.10", "rust-embed", "rustix 1.1.4", @@ -1150,7 +1133,7 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "indexmap 2.14.0", - "libcosmic", + "libcosmic-yoda", "nmrs", "rust-embed", "rustc-hash 2.1.2", @@ -1173,7 +1156,7 @@ dependencies = [ "futures-util", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "tokio", "tracing", @@ -1189,7 +1172,7 @@ version = "1.0.15" dependencies = [ "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "logind-zbus", "rust-embed", "rustix 1.1.4", @@ -1205,7 +1188,7 @@ name = "cosmic-applet-status-area" version = "1.0.15" dependencies = [ "futures", - "libcosmic", + "libcosmic-yoda", "rustc-hash 2.1.2", "serde", "tokio", @@ -1225,7 +1208,7 @@ dependencies = [ "cosmic-protocols", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "rustc-hash 2.1.2", "tokio", @@ -1243,7 +1226,7 @@ dependencies = [ "i18n-embed-fl", "icu", "jiff", - "libcosmic", + "libcosmic-yoda", "logind-zbus", "rust-embed", "timedate-zbus", @@ -1263,7 +1246,7 @@ dependencies = [ "futures", "i18n-embed", "i18n-embed-fl", - "libcosmic", + "libcosmic-yoda", "rust-embed", "tokio", "tracing", @@ -1290,7 +1273,7 @@ dependencies = [ "cosmic-applet-time", "cosmic-applet-workspaces", "cosmic-panel-button", - "libcosmic", + "libcosmic-yoda", "tracing", "tracing-log", "tracing-subscriber", @@ -1308,7 +1291,6 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols//?branch=main#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ "bitflags 2.11.1", "cosmic-protocols", @@ -1330,7 +1312,6 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1351,7 +1332,6 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "quote", "syn", @@ -1360,7 +1340,6 @@ dependencies = [ [[package]] name = "cosmic-dbus-a11y" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -1368,7 +1347,6 @@ dependencies = [ [[package]] name = "cosmic-dbus-networkmanager" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "bitflags 2.11.1", "derive_builder", @@ -1381,7 +1359,6 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#cb0a2f299dbc443697ce1674065e0d4f82915c02" dependencies = [ "bstr", "btoi", @@ -1395,7 +1372,6 @@ dependencies = [ [[package]] name = "cosmic-notifications-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-notifications#a899bfbc6715c36b1f02d7a0f4d3601a3ea0295f" dependencies = [ "cosmic-config", "serde", @@ -1404,10 +1380,9 @@ dependencies = [ [[package]] name = "cosmic-notifications-util" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-notifications#a899bfbc6715c36b1f02d7a0f4d3601a3ea0295f" dependencies = [ "fast_image_resize", - "libcosmic", + "libcosmic-yoda", "serde", "tl", "tracing", @@ -1420,7 +1395,7 @@ name = "cosmic-panel-button" version = "1.0.15" dependencies = [ "cosmic-config", - "libcosmic", + "libcosmic-yoda", "rustc-hash 2.1.2", "serde", "tracing", @@ -1431,7 +1406,6 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#546a6c45210574caed9a3e51446aa8ad622d3627" dependencies = [ "anyhow", "cosmic-config", @@ -1445,7 +1419,6 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols//?branch=main#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ "bitflags 2.11.1", "wayland-backend", @@ -1459,7 +1432,6 @@ dependencies = [ [[package]] name = "cosmic-settings-a11y-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "cosmic-protocols", "iced_futures", @@ -1473,7 +1445,6 @@ dependencies = [ [[package]] name = "cosmic-settings-accessibility-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "cosmic-dbus-a11y", "futures", @@ -1486,7 +1457,6 @@ dependencies = [ [[package]] name = "cosmic-settings-audio-client" version = "1.0.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#e7936f0d4f01c8c5a436908c7ee9f6ad43e6a7d8" dependencies = [ "cosmic-settings-audio-core", "dirs", @@ -1502,7 +1472,6 @@ dependencies = [ [[package]] name = "cosmic-settings-audio-core" version = "1.0.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#e7936f0d4f01c8c5a436908c7ee9f6ad43e6a7d8" dependencies = [ "dirs", "ron 0.12.1", @@ -1513,7 +1482,6 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#fa82bdf9fe7b5f5bd6008f32f393efd5e7a71c47" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1525,8 +1493,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" -version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" +version = "0.1.1-yoda.1" dependencies = [ "zbus", ] @@ -1534,7 +1501,6 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "futures", "iced_futures", @@ -1547,7 +1513,6 @@ dependencies = [ [[package]] name = "cosmic-settings-network-manager-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "bitflags 2.11.1", "cosmic-dbus-networkmanager", @@ -1566,7 +1531,6 @@ dependencies = [ [[package]] name = "cosmic-settings-upower-subscription" version = "1.0.7" -source = "git+https://github.com/pop-os/cosmic-settings#1f225d19ce582423fe8713fc6669c51d162f256f" dependencies = [ "futures", "iced_futures", @@ -1580,8 +1544,6 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.11.1", "fontdb", @@ -1599,18 +1561,19 @@ 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#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "almost", "configparser", "cosmic-config", "csscolorparser", "dirs", + "hex_color", "palette", "ron 0.12.1", "serde", @@ -1651,7 +1614,6 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" -source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a" dependencies = [ "cosmic-text", "etagere", @@ -1688,15 +1650,6 @@ dependencies = [ "uncased", ] -[[package]] -name = "ctor" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf" -dependencies = [ - "dtor", -] - [[package]] name = "cursor-icon" version = "1.2.0" @@ -1961,7 +1914,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1999,7 +1952,6 @@ 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.11.1", "mime 0.1.0", @@ -2026,20 +1978,6 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" - -[[package]] -name = "drm" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" -dependencies = [ - "bitflags 2.11.1", - "bytemuck", - "drm-ffi 0.7.1", - "drm-fourcc", - "rustix 0.38.44", -] [[package]] name = "drm" @@ -2049,29 +1987,19 @@ checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" dependencies = [ "bitflags 2.11.1", "bytemuck", - "drm-ffi 0.9.1", + "drm-ffi", "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 0.8.1", + "drm-sys", "rustix 1.1.4", ] @@ -2081,16 +2009,6 @@ 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" @@ -2101,12 +2019,6 @@ dependencies = [ "linux-raw-sys 0.9.4", ] -[[package]] -name = "dtor" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b" - [[package]] name = "dyn-clone" version = "1.0.20" @@ -2159,7 +2071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2580,16 +2492,6 @@ dependencies = [ "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" @@ -2831,6 +2733,17 @@ 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" @@ -2949,7 +2862,6 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "dnd", "iced_accessibility", @@ -2970,7 +2882,6 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "accesskit", "accesskit_winit", @@ -2979,7 +2890,6 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3004,7 +2914,6 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_core", "iced_futures", @@ -3014,7 +2923,6 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "futures", "iced_core", @@ -3028,7 +2936,6 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3049,7 +2956,6 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_graphics", "iced_runtime", @@ -3058,7 +2964,6 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3070,7 +2975,6 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3085,7 +2989,6 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "bytemuck", "cosmic-text", @@ -3102,9 +3005,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ - "as-raw-xcb-connection", "bitflags 2.11.1", "bytemuck", "cosmic-client-toolkit", @@ -3121,19 +3022,16 @@ dependencies = [ "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#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3151,7 +3049,6 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3793,7 +3690,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3944,7 +3841,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a1886916523694cd6ea3d175f03a1e5010699a2a4cc13696d83d7bea1d80638" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4007,9 +3904,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] -name = "libcosmic" -version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic#758c13723fc35b1d82d7fa4f35859c9f7f3c1b0c" +name = "libcosmic-yoda" +version = "0.1.0-yoda.2" dependencies = [ "apply", "ashpd 0.12.3", @@ -4023,6 +3919,7 @@ dependencies = [ "cosmic-theme", "css-color", "derive_setters", + "enumflags2", "float-cmp 0.10.0", "freedesktop-desktop-entry", "futures", @@ -4129,12 +4026,6 @@ 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" @@ -4330,7 +4221,6 @@ 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", ] @@ -4376,7 +4266,6 @@ dependencies = [ [[package]] name = "mpris2-zbus" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "futures-util", "jiff", @@ -4463,7 +4352,6 @@ dependencies = [ [[package]] name = "nm-secret-agent-manager" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -4530,7 +4418,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5374,6 +5262,8 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -5383,10 +5273,20 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "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" @@ -5402,6 +5302,9 @@ 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" @@ -5696,7 +5599,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6070,7 +5973,6 @@ 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", @@ -6101,14 +6003,11 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" -source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#c2b2c19ddb38ff17495643699f97cb1f2064a1be" dependencies = [ - "as-raw-xcb-connection", "bytemuck", "cfg_aliases", "cocoa", "core-graphics", - "drm 0.11.1", "fastrand", "foreign-types", "js-sys", @@ -6118,14 +6017,12 @@ dependencies = [ "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]] @@ -6222,7 +6119,6 @@ dependencies = [ [[package]] name = "switcheroo-control" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -6283,10 +6179,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6381,7 +6277,6 @@ dependencies = [ [[package]] name = "timedate-zbus" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus", ] @@ -6412,19 +6307,6 @@ dependencies = [ "strict-num", ] -[[package]] -name = "tiny-xlib" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4" -dependencies = [ - "as-raw-xcb-connection", - "ctor", - "libloading", - "pkg-config", - "tracing", -] - [[package]] name = "tinystr" version = "0.8.3" @@ -6768,7 +6650,6 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "upower_dbus" version = "0.3.2" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "serde", "serde_repr", @@ -7343,7 +7224,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -7355,12 +7236,10 @@ 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", @@ -7800,7 +7679,6 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cfg_aliases", @@ -7820,13 +7698,11 @@ 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#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", "bitflags 2.11.1", @@ -7841,7 +7717,6 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -7863,7 +7738,6 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -7871,14 +7745,12 @@ dependencies = [ "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#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -7892,7 +7764,6 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "dpi", @@ -7908,7 +7779,6 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -7928,7 +7798,6 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", "bitflags 2.11.1", @@ -7954,7 +7823,6 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", "bitflags 2.11.1", @@ -7976,7 +7844,6 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -7989,29 +7856,6 @@ 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#f737f1f5900b3399b56951305b0f155afc9c9ee5" -dependencies = [ - "bitflags 2.11.1", - "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" @@ -8130,39 +7974,6 @@ 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" @@ -8178,7 +7989,6 @@ checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#546a6c45210574caed9a3e51446aa8ad622d3627" dependencies = [ "serde", "wayland-protocols-wlr", @@ -8652,3 +8462,15 @@ dependencies = [ "syn", "winnow", ] + +[[patch.unused]] +name = "cosmic-settings-airplane-mode-subscription" +version = "1.0.7" + +[[patch.unused]] +name = "cosmic-settings-sound-subscription" +version = "1.0.7" + +[[patch.unused]] +name = "winit-x11" +version = "0.31.0-beta.2"