battery: Use cosmic-settings-subscriptions for upower subscriptions
These should be useful in `cosmic-osd` as well.
This commit is contained in:
parent
4e3eb0a396
commit
901a70d7a1
6 changed files with 21 additions and 230 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
|
@ -950,6 +950,7 @@ dependencies = [
|
|||
name = "cosmic-applet-battery"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmic-settings-subscriptions",
|
||||
"cosmic-time",
|
||||
"drm",
|
||||
"futures",
|
||||
|
|
@ -1320,6 +1321,21 @@ dependencies = [
|
|||
"zbus 4.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-settings-subscriptions"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-settings-subscriptions#a223eb4d32773e7b1170696f8b2d2d7ab54fa2e1"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_futures",
|
||||
"libpulse-binding",
|
||||
"log",
|
||||
"rustix 0.38.34",
|
||||
"tokio",
|
||||
"upower_dbus",
|
||||
"zbus 4.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-text"
|
||||
version = "0.11.2"
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@ udev = "0.8"
|
|||
zbus.workspace = true
|
||||
# TODO branch
|
||||
upower_dbus = { git = "https://github.com/pop-os/dbus-settings-bindings", branch = "upower" }
|
||||
cosmic-settings-subscriptions = { git = "https://github.com/pop-os/cosmic-settings-subscriptions" }
|
||||
|
|
|
|||
|
|
@ -8,10 +8,6 @@ use crate::backlight::{
|
|||
use crate::config;
|
||||
use crate::dgpu::{dgpu_subscription, Entry, GpuUpdate};
|
||||
use crate::fl;
|
||||
use crate::upower_device::{device_subscription, DeviceDbusEvent};
|
||||
use crate::upower_kbdbacklight::{
|
||||
kbd_backlight_subscription, KeyboardBacklightRequest, KeyboardBacklightUpdate,
|
||||
};
|
||||
use cosmic::applet::cosmic_panel_config::PanelAnchor;
|
||||
use cosmic::applet::token::subscription::{
|
||||
activation_token_subscription, TokenRequest, TokenUpdate,
|
||||
|
|
@ -32,6 +28,10 @@ use cosmic::iced_widget::{Column, Row};
|
|||
use cosmic::widget::{divider, horizontal_space, icon, scrollable, vertical_space};
|
||||
use cosmic::Command;
|
||||
use cosmic::{Element, Theme};
|
||||
use cosmic_settings_subscriptions::upower::{
|
||||
device::{device_subscription, DeviceDbusEvent},
|
||||
kbdbacklight::{kbd_backlight_subscription, KeyboardBacklightRequest, KeyboardBacklightUpdate},
|
||||
};
|
||||
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ mod backend;
|
|||
mod config;
|
||||
mod dgpu;
|
||||
mod localize;
|
||||
mod upower_device;
|
||||
mod upower_kbdbacklight;
|
||||
|
||||
use localize::localize;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,131 +0,0 @@
|
|||
//! # DBus interface proxy for: `org.freedesktop.UPower.Device`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data.
|
||||
//! Source: `Interface '/org/freedesktop/UPower/devices/DisplayDevice' from service 'org.freedesktop.UPower' on system bus`.
|
||||
|
||||
use cosmic::iced::{
|
||||
self,
|
||||
futures::{SinkExt, StreamExt},
|
||||
subscription,
|
||||
};
|
||||
|
||||
use std::{fmt::Debug, hash::Hash};
|
||||
|
||||
use upower_dbus::{BatteryType, DeviceProxy, UPowerProxy};
|
||||
|
||||
pub fn device_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
|
||||
id: I,
|
||||
) -> iced::Subscription<DeviceDbusEvent> {
|
||||
subscription::channel(id, 50, move |mut output| async move {
|
||||
let mut state = State::Ready;
|
||||
|
||||
loop {
|
||||
state = start_listening(state, &mut output).await;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum State {
|
||||
Ready,
|
||||
Waiting(UPowerProxy<'static>, DeviceProxy<'static>),
|
||||
Finished,
|
||||
}
|
||||
|
||||
async fn display_device() -> zbus::Result<(UPowerProxy<'static>, DeviceProxy<'static>)> {
|
||||
let connection = zbus::Connection::system().await?;
|
||||
let upower: UPowerProxy<'_> = UPowerProxy::new(&connection).await?;
|
||||
let device_path = upower.get_display_device().await?;
|
||||
Ok((upower, device_path))
|
||||
}
|
||||
|
||||
async fn start_listening(
|
||||
state: State,
|
||||
output: &mut futures::channel::mpsc::Sender<DeviceDbusEvent>,
|
||||
) -> State {
|
||||
match state {
|
||||
State::Ready => {
|
||||
if let Ok((upower, device)) = display_device().await {
|
||||
if let Ok(devices) = upower.enumerate_devices().await {
|
||||
let mut has_battery = false;
|
||||
for device in devices {
|
||||
let Ok(d) = DeviceProxy::builder(upower.inner().connection()).path(device)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let Ok(d) = d.build().await else {
|
||||
continue;
|
||||
};
|
||||
if d.type_().await == Ok(BatteryType::Battery)
|
||||
&& d.power_supply().await.unwrap_or_default()
|
||||
{
|
||||
has_battery = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !has_battery {
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
_ = output
|
||||
.send(DeviceDbusEvent::Update {
|
||||
on_battery: upower
|
||||
.cached_on_battery()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
percent: device
|
||||
.cached_percentage()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
time_to_empty: device
|
||||
.cached_time_to_empty()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
.await;
|
||||
return State::Waiting(upower, device);
|
||||
}
|
||||
State::Finished
|
||||
}
|
||||
State::Waiting(upower, device) => {
|
||||
let mut stream = futures::stream_select!(
|
||||
upower.receive_on_battery_changed().await.map(|_| ()),
|
||||
device.receive_percentage_changed().await.map(|_| ()),
|
||||
device.receive_time_to_empty_changed().await.map(|_| ()),
|
||||
);
|
||||
match stream.next().await {
|
||||
Some(_) => {
|
||||
_ = output
|
||||
.send(DeviceDbusEvent::Update {
|
||||
on_battery: upower
|
||||
.cached_on_battery()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
percent: device
|
||||
.cached_percentage()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
time_to_empty: device
|
||||
.cached_time_to_empty()
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
.await;
|
||||
|
||||
State::Waiting(upower, device)
|
||||
}
|
||||
None => State::Finished,
|
||||
}
|
||||
}
|
||||
State::Finished => iced::futures::future::pending().await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DeviceDbusEvent {
|
||||
Update {
|
||||
on_battery: bool,
|
||||
percent: f64,
|
||||
time_to_empty: i64,
|
||||
},
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
//! # DBus interface proxy for: `org.freedesktop.UPower.KbdBacklight`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data.
|
||||
//! Source: `Interface '/org/freedesktop/UPower/KbdBacklight' from service 'org.freedesktop.UPower' on system bus`.
|
||||
|
||||
use cosmic::iced::{self, futures::SinkExt, subscription};
|
||||
use std::{fmt::Debug, hash::Hash};
|
||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
|
||||
|
||||
use upower_dbus::KbdBacklightProxy;
|
||||
|
||||
pub fn kbd_backlight_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
|
||||
id: I,
|
||||
) -> iced::Subscription<KeyboardBacklightUpdate> {
|
||||
subscription::channel(id, 50, move |mut output| async move {
|
||||
let mut state = State::Ready;
|
||||
|
||||
loop {
|
||||
state = start_listening(state, &mut output).await;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum State {
|
||||
Ready,
|
||||
Waiting(
|
||||
KbdBacklightProxy<'static>,
|
||||
UnboundedReceiver<KeyboardBacklightRequest>,
|
||||
),
|
||||
Finished,
|
||||
}
|
||||
|
||||
async fn get_brightness(kbd_proxy: &KbdBacklightProxy<'_>) -> zbus::Result<f64> {
|
||||
Ok(kbd_proxy.get_brightness().await? as f64 / kbd_proxy.get_max_brightness().await? as f64)
|
||||
}
|
||||
|
||||
async fn start_listening(
|
||||
state: State,
|
||||
output: &mut futures::channel::mpsc::Sender<KeyboardBacklightUpdate>,
|
||||
) -> State {
|
||||
match state {
|
||||
State::Ready => {
|
||||
let conn = match zbus::Connection::system().await {
|
||||
Ok(conn) => conn,
|
||||
Err(_) => return State::Finished,
|
||||
};
|
||||
let kbd_proxy = match KbdBacklightProxy::builder(&conn).build().await {
|
||||
Ok(p) => p,
|
||||
Err(_) => return State::Finished,
|
||||
};
|
||||
let (tx, rx) = unbounded_channel();
|
||||
|
||||
let b = get_brightness(&kbd_proxy).await.ok();
|
||||
_ = output.send(KeyboardBacklightUpdate::Sender(tx)).await;
|
||||
_ = output.send(KeyboardBacklightUpdate::Brightness(b)).await;
|
||||
|
||||
State::Waiting(kbd_proxy, rx)
|
||||
}
|
||||
State::Waiting(proxy, mut rx) => match rx.recv().await {
|
||||
Some(req) => match req {
|
||||
KeyboardBacklightRequest::Get => {
|
||||
let b = get_brightness(&proxy).await.ok();
|
||||
_ = output.send(KeyboardBacklightUpdate::Brightness(b)).await;
|
||||
State::Waiting(proxy, rx)
|
||||
}
|
||||
KeyboardBacklightRequest::Set(value) => {
|
||||
if let Ok(max_brightness) = proxy.get_max_brightness().await {
|
||||
let value = value.clamp(0., 1.) * (max_brightness as f64);
|
||||
let value = value.round() as i32;
|
||||
let _ = proxy.set_brightness(value).await;
|
||||
}
|
||||
|
||||
State::Waiting(proxy, rx)
|
||||
}
|
||||
},
|
||||
None => State::Finished,
|
||||
},
|
||||
State::Finished => iced::futures::future::pending().await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KeyboardBacklightUpdate {
|
||||
Sender(UnboundedSender<KeyboardBacklightRequest>),
|
||||
Brightness(Option<f64>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KeyboardBacklightRequest {
|
||||
Get,
|
||||
Set(f64),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue