fix: update and fixes for bluetooth

This commit is contained in:
Ashley Wulber 2023-12-05 14:19:44 -05:00 • committed by Ashley Wulber
parent 0e84d0f3cb
commit 158139d466
8 changed files with 110 additions and 67 deletions

49
Cargo.lock generated
View file

@ -830,6 +830,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bluer", "bluer",
"cosmic-time",
"futures", "futures",
"futures-util", "futures-util",
"i18n-embed 0.13.9", "i18n-embed 0.13.9",
@ -994,7 +995,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config" name = "cosmic-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"cosmic-config-derive", "cosmic-config-derive",
@ -1008,7 +1009,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config-derive" name = "cosmic-config-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",
@ -1109,7 +1110,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-theme" name = "cosmic-theme"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"almost", "almost",
"cosmic-config", "cosmic-config",
@ -1123,7 +1124,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-time" name = "cosmic-time"
version = "0.4.0" 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 = [ dependencies = [
"float-cmp", "float-cmp",
"libcosmic", "libcosmic",
@ -2593,7 +2594,7 @@ dependencies = [
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"iced_accessibility", "iced_accessibility",
"iced_core", "iced_core",
@ -2608,7 +2609,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_accessibility" name = "iced_accessibility"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_unix", "accesskit_unix",
@ -2617,7 +2618,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_core" name = "iced_core"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"iced_accessibility", "iced_accessibility",
@ -2634,7 +2635,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_futures" name = "iced_futures"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"futures", "futures",
"iced_core", "iced_core",
@ -2647,7 +2648,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_graphics" name = "iced_graphics"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"bytemuck", "bytemuck",
@ -2670,7 +2671,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"iced_graphics", "iced_graphics",
"iced_tiny_skia", "iced_tiny_skia",
@ -2683,7 +2684,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_runtime" name = "iced_runtime"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"iced_accessibility", "iced_accessibility",
"iced_core", "iced_core",
@ -2695,7 +2696,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_sctk" name = "iced_sctk"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"enum-repr", "enum-repr",
"float-cmp", "float-cmp",
@ -2719,7 +2720,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_style" name = "iced_style"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"iced_core", "iced_core",
"once_cell", "once_cell",
@ -2729,7 +2730,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_tiny_skia" name = "iced_tiny_skia"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
@ -2747,7 +2748,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_wgpu" name = "iced_wgpu"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"bytemuck", "bytemuck",
@ -2767,7 +2768,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_widget" name = "iced_widget"
version = "0.12.0" version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"iced_renderer", "iced_renderer",
"iced_runtime", "iced_runtime",
@ -3035,7 +3036,7 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#cda781cb96875c1c3b9cf648393ae4f325a1d34d" source = "git+https://github.com/pop-os/libcosmic#283aa2abd06d83abf0b8f9c1e38259599d05516a"
dependencies = [ dependencies = [
"apply", "apply",
"ashpd", "ashpd",
@ -4682,7 +4683,7 @@ dependencies = [
[[package]] [[package]]
name = "smithay-client-toolkit" name = "smithay-client-toolkit"
version = "0.18.0" 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 = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"bytemuck", "bytemuck",
@ -5289,18 +5290,18 @@ dependencies = [
[[package]] [[package]]
name = "unic-langid" name = "unic-langid"
version = "0.9.1" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" checksum = "887622f8e7b723780c5e64b04dcc0c9b8f426ada7cca6790cd3ea3bf0f08037a"
dependencies = [ dependencies = [
"unic-langid-impl", "unic-langid-impl",
] ]
[[package]] [[package]]
name = "unic-langid-impl" name = "unic-langid-impl"
version = "0.9.1" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" checksum = "5adeb847e35eed4efbffd9fb2e4d078b91ece56e4d6a3c0d2df55b3a1dac07d5"
dependencies = [ dependencies = [
"serde", "serde",
"tinystr", "tinystr",
@ -6147,9 +6148,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.5.23" version = "0.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf28f534400ca4195b18033e02c5dd7c36b1138a56f2cfebca48112b528f63" checksum = "0383266b19108dfc6314a56047aa545a1b4d1be60e799b4dbdd407b56402704b"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View file

@ -46,5 +46,5 @@ lto = "thin"
# [patch."https://github.com/pop-os/libcosmic"] # [patch."https://github.com/pop-os/libcosmic"]
# libcosmic = { path = "../libcosmic" } # libcosmic = { path = "../libcosmic" }
# cosmic-config = { path = "../libcosmic/cosmic-config" } # 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" } sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "e63ab5f" }

View file

@ -758,6 +758,7 @@ impl cosmic::Application for Audio {
Message::ToggleMediaControlsInTopPanel, Message::ToggleMediaControlsInTopPanel,
) )
.text_size(14) .text_size(14)
.width(Length::Fill)
) )
.padding([0, 24]), .padding([0, 24]),
padded_control(divider::horizontal::default()), padded_control(divider::horizontal::default()),

View file

@ -9,6 +9,7 @@ once_cell = "1.16.0"
bluer = { version = "0.15", features = ["bluetoothd", "id"] } bluer = { version = "0.15", features = ["bluetoothd", "id"] }
futures-util = "0.3.21" futures-util = "0.3.21"
libcosmic.workspace = true libcosmic.workspace = true
cosmic-time.workspace = true
futures = "0.3" futures = "0.3"
log = "0.4" log = "0.4"
pretty_env_logger = "0.5" pretty_env_logger = "0.5"

View file

@ -19,9 +19,10 @@ use cosmic::{
window, window,
}, },
iced_style::application, iced_style::application,
widget::{button, divider, icon, toggler}, widget::{button, divider, icon},
Element, Theme, Element, Theme,
}; };
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
@ -29,6 +30,8 @@ use tokio::sync::mpsc::Sender;
use crate::bluetooth::{bluetooth_subscription, BluerDevice, BluerEvent}; use crate::bluetooth::{bluetooth_subscription, BluerDevice, BluerEvent};
use crate::{config, fl}; use crate::{config, fl};
static BLUETOOTH_ENABLED: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);
pub fn run() -> cosmic::iced::Result { pub fn run() -> cosmic::iced::Result {
cosmic::applet::run::<CosmicBluetoothApplet>(false, ()) cosmic::applet::run::<CosmicBluetoothApplet>(false, ())
} }
@ -45,6 +48,7 @@ struct CosmicBluetoothApplet {
show_visible_devices: bool, show_visible_devices: bool,
request_confirmation: Option<(BluerDevice, String, Sender<bool>)>, request_confirmation: Option<(BluerDevice, String, Sender<bool>)>,
token_tx: Option<calloop::channel::Sender<TokenRequest>>, token_tx: Option<calloop::channel::Sender<TokenRequest>>,
timeline: Timeline,
} }
impl CosmicBluetoothApplet { impl CosmicBluetoothApplet {
@ -70,6 +74,8 @@ enum Message {
Confirm, Confirm,
Token(TokenUpdate), Token(TokenUpdate),
OpenSettings, OpenSettings,
Frame(Instant),
ToggleBluetooth(chain::Toggler, bool),
} }
impl cosmic::Application for CosmicBluetoothApplet { impl cosmic::Application for CosmicBluetoothApplet {
@ -155,6 +161,16 @@ impl cosmic::Application for CosmicBluetoothApplet {
if let Some(err_msg) = err_msg { if let Some(err_msg) = err_msg {
eprintln!("bluetooth request error: {}", 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; self.bluer_state = state;
// TODO special handling for some requests // TODO special handling for some requests
match req { match req {
@ -162,14 +178,11 @@ impl cosmic::Application for CosmicBluetoothApplet {
if self.popup.is_some() && self.bluer_sender.is_some() => if self.popup.is_some() && self.bluer_sender.is_some() =>
{ {
let tx = self.bluer_sender.as_ref().cloned().unwrap(); let tx = self.bluer_sender.as_ref().cloned().unwrap();
return iced::Command::perform( tokio::spawn(async move {
async move { // sleep for a bit before requesting state update again
// sleep for a bit before requesting state update again tokio::time::sleep(Duration::from_millis(3000)).await;
tokio::time::sleep(Duration::from_millis(3000)).await; let _ = tx.send(BluerRequest::StateUpdate).await;
let _ = tx.send(BluerRequest::StateUpdate).await; });
},
|_| cosmic::app::message::app(Message::Ignore),
);
} }
_ => {} _ => {}
}; };
@ -223,9 +236,6 @@ impl cosmic::Application for CosmicBluetoothApplet {
match &r { match &r {
BluerRequest::SetBluetoothEnabled(enabled) => { BluerRequest::SetBluetoothEnabled(enabled) => {
self.bluer_state.bluetooth_enabled = *enabled; self.bluer_state.bluetooth_enabled = *enabled;
if !*enabled {
self.bluer_state = BluerState::default();
}
} }
BluerRequest::ConnectDevice(add) => { BluerRequest::ConnectDevice(add) => {
if let Some(d) = self if let Some(d) = self
@ -260,32 +270,23 @@ impl cosmic::Application for CosmicBluetoothApplet {
_ => {} // TODO _ => {} // TODO
} }
if let Some(tx) = self.bluer_sender.as_mut().cloned() { if let Some(tx) = self.bluer_sender.as_mut().cloned() {
return iced::Command::perform( tokio::spawn(async move {
async move { let _ = tx.send(r).await;
let _ = tx.send(r).await; });
},
|_| cosmic::app::message::app(Message::Ignore), // Error handling
);
} }
} }
Message::Cancel => { Message::Cancel => {
if let Some((_, _, tx)) = self.request_confirmation.take() { if let Some((_, _, tx)) = self.request_confirmation.take() {
return iced::Command::perform( tokio::spawn(async move {
async move { let _ = tx.send(false).await;
let _ = tx.send(false).await; });
},
|_| cosmic::app::message::app(Message::Ignore),
);
} }
} }
Message::Confirm => { Message::Confirm => {
if let Some((_, _, tx)) = self.request_confirmation.take() { if let Some((_, _, tx)) = self.request_confirmation.take() {
return iced::Command::perform( tokio::spawn(async move {
async move { let _ = tx.send(true).await;
let _ = tx.send(true).await; });
},
|_| cosmic::app::message::app(Message::Ignore),
);
} }
} }
Message::CloseRequested(id) => { Message::CloseRequested(id) => {
@ -319,6 +320,19 @@ impl cosmic::Application for CosmicBluetoothApplet {
cosmic::process::spawn(cmd); 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(); self.update_icon();
Command::none() Command::none()
@ -391,9 +405,14 @@ impl cosmic::Application for CosmicBluetoothApplet {
let mut content = column![ let mut content = column![
column![padded_control( column![padded_control(
toggler(fl!("bluetooth"), self.bluer_state.bluetooth_enabled, |m| { anim!(
Message::Request(BluerRequest::SetBluetoothEnabled(m)) //toggler
},) BLUETOOTH_ENABLED,
&self.timeline,
fl!("bluetooth"),
self.bluer_state.bluetooth_enabled,
Message::ToggleBluetooth,
)
.text_size(14) .text_size(14)
.width(Length::Fill) .width(Length::Fill)
),], ),],
@ -536,6 +555,9 @@ impl cosmic::Application for CosmicBluetoothApplet {
Subscription::batch(vec![ Subscription::batch(vec![
activation_token_subscription(0).map(Message::Token), activation_token_subscription(0).map(Message::Token),
bluetooth_subscription(0).map(Message::BluetoothEvent), bluetooth_subscription(0).map(Message::BluetoothEvent),
self.timeline
.as_subscription()
.map(|(_, now)| Message::Frame(now)),
]) ])
} }

View file

@ -471,10 +471,34 @@ impl BluerSessionState {
}; };
self_.process_requests(request_rx); self_.process_requests(request_rx);
self_.process_changes(); self_.process_changes();
self_.listen_bluetooth_power_changes();
Ok(self_) Ok(self_)
} }
fn listen_bluetooth_power_changes(&self) {
let tx = self.tx.clone();
let adapter_clone = self.adapter.clone();
let _handle: JoinHandle<anyhow::Result<()>> = 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... // Note: For some reason, this doesn't actually seem to work so well. it seems unreliable...
pub(crate) fn process_changes(&self) { pub(crate) fn process_changes(&self) {
let tx = self.tx.clone(); let tx = self.tx.clone();
@ -482,7 +506,6 @@ impl BluerSessionState {
let _monitor_devices: tokio::task::JoinHandle<Result<(), anyhow::Error>> = let _monitor_devices: tokio::task::JoinHandle<Result<(), anyhow::Error>> =
spawn(async move { spawn(async move {
let mut change_stream = adapter_clone.discover_devices_with_changes().await?; let mut change_stream = adapter_clone.discover_devices_with_changes().await?;
let mut devices_changed = false; let mut devices_changed = false;
let mut milli_timeout = 10; let mut milli_timeout = 10;
'outer: loop { 'outer: loop {
@ -544,12 +567,6 @@ impl BluerSessionState {
if let Err(e) = res { if let Err(e) = res {
err_msg = Some(e.to_string()); 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) => { BluerRequest::PairDevice(address) => {
let res = adapter_clone.device(*address); let res = adapter_clone.device(*address);

View file

@ -6,5 +6,5 @@ mod window;
fn main() -> cosmic::iced::Result { fn main() -> cosmic::iced::Result {
localize::localize(); localize::localize();
cosmic::applet::run::<Window>(true, ()) cosmic::applet::run::<Window>(false, ())
} }

View file

@ -242,7 +242,8 @@ impl cosmic::Application for Window {
) )
.text_size(14) .text_size(14)
.width(Length::Fill), .width(Length::Fill),
)), ))
.width(Length::Fill),
padded_control(row!( padded_control(row!(
text(fl!("navigate-windows")).size(14).width(Length::Fill), text(fl!("navigate-windows")).size(14).width(Length::Fill),
text(format!("{} + {}", fl!("super"), fl!("arrow-keys"))).size(14), text(format!("{} + {}", fl!("super"), fl!("arrow-keys"))).size(14),