diff --git a/Cargo.lock b/Cargo.lock index fa4f59e6..6dad1c84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -830,6 +830,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bluer", + "cosmic-time", "futures", "futures-util", "i18n-embed 0.13.9", @@ -994,7 +995,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1008,7 +1009,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "quote", "syn 1.0.109", @@ -1109,7 +1110,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "almost", "cosmic-config", @@ -1123,7 +1124,7 @@ dependencies = [ [[package]] name = "cosmic-time" version = "0.4.0" -source = "git+https://github.com/pop-os/cosmic-time#2f67ad8073982af7808785d102d6cd2ab9b72ec7" +source = "git+https://github.com/pop-os/cosmic-time#4dc1fcec44aa7471a8e707fa391f9882d23250d7" dependencies = [ "float-cmp", "libcosmic", @@ -2593,7 +2594,7 @@ dependencies = [ [[package]] name = "iced" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "iced_accessibility", "iced_core", @@ -2608,7 +2609,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "accesskit", "accesskit_unix", @@ -2617,7 +2618,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "bitflags 1.3.2", "iced_accessibility", @@ -2634,7 +2635,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "futures", "iced_core", @@ -2647,7 +2648,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2670,7 +2671,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2683,7 +2684,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "iced_accessibility", "iced_core", @@ -2695,7 +2696,7 @@ dependencies = [ [[package]] name = "iced_sctk" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "enum-repr", "float-cmp", @@ -2719,7 +2720,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "iced_core", "once_cell", @@ -2729,7 +2730,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "bytemuck", "cosmic-text", @@ -2747,7 +2748,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2767,7 +2768,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "iced_renderer", "iced_runtime", @@ -3035,7 +3036,7 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" +source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a" dependencies = [ "apply", "ashpd", @@ -4682,7 +4683,7 @@ dependencies = [ [[package]] name = "smithay-client-toolkit" version = "0.18.0" -source = "git+https://github.com/smithay/client-toolkit//?rev=e63ab5f#e63ab5f01964bc48766fc4c3bf79cc05dc59874c" +source = "git+https://github.com/smithay/client-toolkit?rev=2e9bf9f#2e9bf9f31698851ca373e5f1e7ba3e6e804e4db1" dependencies = [ "bitflags 2.4.1", "bytemuck", @@ -5289,18 +5290,18 @@ dependencies = [ [[package]] name = "unic-langid" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" +checksum = "887622f8e7b723780c5e64b04dcc0c9b8f426ada7cca6790cd3ea3bf0f08037a" dependencies = [ "unic-langid-impl", ] [[package]] name = "unic-langid-impl" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" +checksum = "5adeb847e35eed4efbffd9fb2e4d078b91ece56e4d6a3c0d2df55b3a1dac07d5" dependencies = [ "serde", "tinystr", @@ -6147,9 +6148,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.23" +version = "0.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf28f534400ca4195b18033e02c5dd7c36b1138a56f2cfebca48112b528f63" +checksum = "0383266b19108dfc6314a56047aa545a1b4d1be60e799b4dbdd407b56402704b" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 443e79ff..05a78d89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,5 +46,5 @@ lto = "thin" # [patch."https://github.com/pop-os/libcosmic"] # libcosmic = { path = "../libcosmic" } # cosmic-config = { path = "../libcosmic/cosmic-config" } -[patch."https://github.com/Smithay/client-toolkit"] +# [patch."https://github.com/Smithay/client-toolkit"] sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "e63ab5f" } diff --git a/cosmic-applet-audio/src/main.rs b/cosmic-applet-audio/src/main.rs index a93f828a..d5d30b12 100644 --- a/cosmic-applet-audio/src/main.rs +++ b/cosmic-applet-audio/src/main.rs @@ -758,6 +758,7 @@ impl cosmic::Application for Audio { Message::ToggleMediaControlsInTopPanel, ) .text_size(14) + .width(Length::Fill) ) .padding([0, 24]), padded_control(divider::horizontal::default()), diff --git a/cosmic-applet-bluetooth/Cargo.toml b/cosmic-applet-bluetooth/Cargo.toml index ec1c745a..544bc221 100644 --- a/cosmic-applet-bluetooth/Cargo.toml +++ b/cosmic-applet-bluetooth/Cargo.toml @@ -9,6 +9,7 @@ once_cell = "1.16.0" bluer = { version = "0.15", features = ["bluetoothd", "id"] } futures-util = "0.3.21" libcosmic.workspace = true +cosmic-time.workspace = true futures = "0.3" log = "0.4" pretty_env_logger = "0.5" diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index fbfbfd74..d3cdb7e1 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -19,9 +19,10 @@ use cosmic::{ window, }, iced_style::application, - widget::{button, divider, icon, toggler}, + widget::{button, divider, icon}, Element, Theme, }; +use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline}; use std::collections::HashMap; use std::time::Duration; use tokio::sync::mpsc::Sender; @@ -29,6 +30,8 @@ use tokio::sync::mpsc::Sender; use crate::bluetooth::{bluetooth_subscription, BluerDevice, BluerEvent}; use crate::{config, fl}; +static BLUETOOTH_ENABLED: Lazy = Lazy::new(id::Toggler::unique); + pub fn run() -> cosmic::iced::Result { cosmic::applet::run::(false, ()) } @@ -45,6 +48,7 @@ struct CosmicBluetoothApplet { show_visible_devices: bool, request_confirmation: Option<(BluerDevice, String, Sender)>, token_tx: Option>, + timeline: Timeline, } impl CosmicBluetoothApplet { @@ -70,6 +74,8 @@ enum Message { Confirm, Token(TokenUpdate), OpenSettings, + Frame(Instant), + ToggleBluetooth(chain::Toggler, bool), } impl cosmic::Application for CosmicBluetoothApplet { @@ -155,6 +161,16 @@ impl cosmic::Application for CosmicBluetoothApplet { if let Some(err_msg) = err_msg { eprintln!("bluetooth request error: {}", err_msg); } + if self.bluer_state.bluetooth_enabled != state.bluetooth_enabled { + self.timeline + .set_chain(if state.bluetooth_enabled { + chain::Toggler::on(BLUETOOTH_ENABLED.clone(), 1.0) + } else { + chain::Toggler::off(BLUETOOTH_ENABLED.clone(), 1.0) + }) + .start(); + } + self.bluer_state = state; // TODO special handling for some requests match req { @@ -162,14 +178,11 @@ impl cosmic::Application for CosmicBluetoothApplet { if self.popup.is_some() && self.bluer_sender.is_some() => { let tx = self.bluer_sender.as_ref().cloned().unwrap(); - return iced::Command::perform( - async move { - // sleep for a bit before requesting state update again - tokio::time::sleep(Duration::from_millis(3000)).await; - let _ = tx.send(BluerRequest::StateUpdate).await; - }, - |_| cosmic::app::message::app(Message::Ignore), - ); + tokio::spawn(async move { + // sleep for a bit before requesting state update again + tokio::time::sleep(Duration::from_millis(3000)).await; + let _ = tx.send(BluerRequest::StateUpdate).await; + }); } _ => {} }; @@ -223,9 +236,6 @@ impl cosmic::Application for CosmicBluetoothApplet { match &r { BluerRequest::SetBluetoothEnabled(enabled) => { self.bluer_state.bluetooth_enabled = *enabled; - if !*enabled { - self.bluer_state = BluerState::default(); - } } BluerRequest::ConnectDevice(add) => { if let Some(d) = self @@ -260,32 +270,23 @@ impl cosmic::Application for CosmicBluetoothApplet { _ => {} // TODO } if let Some(tx) = self.bluer_sender.as_mut().cloned() { - return iced::Command::perform( - async move { - let _ = tx.send(r).await; - }, - |_| cosmic::app::message::app(Message::Ignore), // Error handling - ); + tokio::spawn(async move { + let _ = tx.send(r).await; + }); } } Message::Cancel => { if let Some((_, _, tx)) = self.request_confirmation.take() { - return iced::Command::perform( - async move { - let _ = tx.send(false).await; - }, - |_| cosmic::app::message::app(Message::Ignore), - ); + tokio::spawn(async move { + let _ = tx.send(false).await; + }); } } Message::Confirm => { if let Some((_, _, tx)) = self.request_confirmation.take() { - return iced::Command::perform( - async move { - let _ = tx.send(true).await; - }, - |_| cosmic::app::message::app(Message::Ignore), - ); + tokio::spawn(async move { + let _ = tx.send(true).await; + }); } } Message::CloseRequested(id) => { @@ -319,6 +320,19 @@ impl cosmic::Application for CosmicBluetoothApplet { cosmic::process::spawn(cmd); } }, + Message::Frame(instant) => self.timeline.now(instant), + Message::ToggleBluetooth(chain, enabled) => { + if self.bluer_state.bluetooth_enabled == enabled { + return Command::none(); + } + self.timeline.set_chain(chain).start(); + self.bluer_state.bluetooth_enabled = enabled; + if let Some(tx) = self.bluer_sender.clone() { + tokio::spawn(async move { + let _ = tx.send(BluerRequest::SetBluetoothEnabled(enabled)).await; + }); + } + } } self.update_icon(); Command::none() @@ -391,9 +405,14 @@ impl cosmic::Application for CosmicBluetoothApplet { let mut content = column![ column![padded_control( - toggler(fl!("bluetooth"), self.bluer_state.bluetooth_enabled, |m| { - Message::Request(BluerRequest::SetBluetoothEnabled(m)) - },) + anim!( + //toggler + BLUETOOTH_ENABLED, + &self.timeline, + fl!("bluetooth"), + self.bluer_state.bluetooth_enabled, + Message::ToggleBluetooth, + ) .text_size(14) .width(Length::Fill) ),], @@ -536,6 +555,9 @@ impl cosmic::Application for CosmicBluetoothApplet { Subscription::batch(vec![ activation_token_subscription(0).map(Message::Token), bluetooth_subscription(0).map(Message::BluetoothEvent), + self.timeline + .as_subscription() + .map(|(_, now)| Message::Frame(now)), ]) } diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index fed2818d..81dc7623 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -471,10 +471,34 @@ impl BluerSessionState { }; self_.process_requests(request_rx); self_.process_changes(); + self_.listen_bluetooth_power_changes(); Ok(self_) } + fn listen_bluetooth_power_changes(&self) { + let tx = self.tx.clone(); + let adapter_clone = self.adapter.clone(); + let _handle: JoinHandle> = spawn(async move { + let mut status = adapter_clone.is_powered().await.unwrap_or_default(); + loop { + tokio::time::sleep(Duration::from_secs(5)).await; + let new_status = adapter_clone.is_powered().await.unwrap_or_default(); + if new_status != status { + status = new_status; + let _ = tx + .send(BluerSessionEvent::ChangesProcessed(BluerState { + devices: build_device_list(&adapter_clone).await, + bluetooth_enabled: status, + discoverable: adapter_clone.is_discoverable().await.unwrap_or_default(), + pairable: adapter_clone.is_pairable().await.unwrap_or_default(), + })) + .await; + } + } + }); + } + // Note: For some reason, this doesn't actually seem to work so well. it seems unreliable... pub(crate) fn process_changes(&self) { let tx = self.tx.clone(); @@ -482,7 +506,6 @@ impl BluerSessionState { let _monitor_devices: tokio::task::JoinHandle> = spawn(async move { let mut change_stream = adapter_clone.discover_devices_with_changes().await?; - let mut devices_changed = false; let mut milli_timeout = 10; 'outer: loop { @@ -544,12 +567,6 @@ impl BluerSessionState { if let Err(e) = res { err_msg = Some(e.to_string()); } - if *enabled { - let res = adapter_clone.set_discoverable(*enabled).await; - if let Err(e) = res { - err_msg = Some(e.to_string()); - } - } } BluerRequest::PairDevice(address) => { let res = adapter_clone.device(*address); diff --git a/cosmic-applet-tiling/src/main.rs b/cosmic-applet-tiling/src/main.rs index c7b8eeee..de23305c 100644 --- a/cosmic-applet-tiling/src/main.rs +++ b/cosmic-applet-tiling/src/main.rs @@ -6,5 +6,5 @@ mod window; fn main() -> cosmic::iced::Result { localize::localize(); - cosmic::applet::run::(true, ()) + cosmic::applet::run::(false, ()) } diff --git a/cosmic-applet-tiling/src/window.rs b/cosmic-applet-tiling/src/window.rs index b3271c2c..f72c17b2 100644 --- a/cosmic-applet-tiling/src/window.rs +++ b/cosmic-applet-tiling/src/window.rs @@ -242,7 +242,8 @@ impl cosmic::Application for Window { ) .text_size(14) .width(Length::Fill), - )), + )) + .width(Length::Fill), padded_control(row!( text(fl!("navigate-windows")).size(14).width(Length::Fill), text(format!("{} + {}", fl!("super"), fl!("arrow-keys"))).size(14),