2024-01-17 12:37:22 -07:00
|
|
|
use cosmic::iced::{
|
2025-02-21 17:05:50 -05:00
|
|
|
Subscription,
|
2025-04-10 13:03:53 +02:00
|
|
|
futures::{SinkExt, StreamExt, channel::mpsc},
|
2024-01-17 12:37:22 -07:00
|
|
|
};
|
2025-04-10 13:03:53 +02:00
|
|
|
use std::{any::TypeId, time::Duration};
|
2024-01-17 12:37:22 -07:00
|
|
|
use upower_dbus::UPowerProxy;
|
|
|
|
|
use zbus::{Connection, Result};
|
|
|
|
|
|
|
|
|
|
pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
|
|
|
|
struct PowerSubscription;
|
|
|
|
|
|
2025-02-21 17:05:50 -05:00
|
|
|
Subscription::run_with_id(
|
2024-01-17 12:37:22 -07:00
|
|
|
TypeId::of::<PowerSubscription>(),
|
2025-02-21 17:05:50 -05:00
|
|
|
cosmic::iced_futures::stream::channel(16, |mut msg_tx| async move {
|
2024-01-17 12:37:22 -07:00
|
|
|
match handler(&mut msg_tx).await {
|
|
|
|
|
Ok(()) => {}
|
|
|
|
|
Err(err) => {
|
2025-09-12 17:39:37 -04:00
|
|
|
tracing::warn!("upower error: {}", err);
|
2024-01-17 12:37:22 -07:00
|
|
|
//TODO: send error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If reading power status failed, clear power icon
|
|
|
|
|
msg_tx.send(None).await.unwrap();
|
|
|
|
|
|
|
|
|
|
//TODO: should we retry on error?
|
2025-04-10 13:03:53 +02:00
|
|
|
futures_util::future::pending().await
|
2025-02-21 17:05:50 -05:00
|
|
|
}),
|
2024-01-17 12:37:22 -07:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO: use never type?
|
|
|
|
|
pub async fn handler(msg_tx: &mut mpsc::Sender<Option<(String, f64)>>) -> Result<()> {
|
|
|
|
|
let zbus = Connection::system().await?;
|
|
|
|
|
let upower = UPowerProxy::new(&zbus).await?;
|
|
|
|
|
let dev = upower.get_display_device().await?;
|
|
|
|
|
|
|
|
|
|
let mut icon_name_changed = dev.receive_icon_name_changed().await;
|
|
|
|
|
let mut percentage_changed = dev.receive_percentage_changed().await;
|
2025-04-10 13:03:53 +02:00
|
|
|
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
|
|
|
|
|
2024-01-17 12:37:22 -07:00
|
|
|
loop {
|
|
|
|
|
let mut info_opt = None;
|
|
|
|
|
|
|
|
|
|
if let Ok(percent) = dev.percentage().await {
|
|
|
|
|
if let Ok(icon_name) = dev.icon_name().await {
|
2024-08-27 15:59:23 -05:00
|
|
|
if !icon_name.is_empty() && !icon_name.eq("battery-missing-symbolic") {
|
2024-01-17 12:37:22 -07:00
|
|
|
info_opt = Some((icon_name, percent));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg_tx.send(info_opt).await.unwrap();
|
|
|
|
|
|
2025-04-10 13:03:53 +02:00
|
|
|
// Waits until icon or percentage have changed, and at least one second has passed.
|
|
|
|
|
futures_util::future::select(icon_name_changed.next(), percentage_changed.next()).await;
|
|
|
|
|
interval.tick().await;
|
2024-01-17 12:37:22 -07:00
|
|
|
}
|
|
|
|
|
}
|