battery: Load properties from UPower, and monitor for changes
This commit is contained in:
parent
ed42b4c71e
commit
e46abe4dc3
4 changed files with 69 additions and 16 deletions
|
|
@ -59,4 +59,17 @@ fn backlight() -> io::Result<Option<Backlight>> {
|
||||||
Ok(best_backlight)
|
Ok(best_backlight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Cache device, max_brightness, etc.
|
||||||
|
async fn set_display_brightness(brightness: f64) -> io::Result<()> {
|
||||||
|
if let Some(backlight) = backlight()? {
|
||||||
|
if let Some(max_brightness) = backlight.max_brightness() {
|
||||||
|
let value = brightness.clamp(0., 1.) * (max_brightness as f64);
|
||||||
|
let value = value.round() as u32;
|
||||||
|
// XXX TODO
|
||||||
|
backlight.set_brightness(todo!(), value).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: keyboard backlight
|
// TODO: keyboard backlight
|
||||||
|
|
|
||||||
|
|
@ -15,33 +15,26 @@ async fn display_device() -> zbus::Result<DeviceProxy<'static>> {
|
||||||
let device_path = upower.get_display_device().await?;
|
let device_path = upower.get_display_device().await?;
|
||||||
DeviceProxy::builder(&connection)
|
DeviceProxy::builder(&connection)
|
||||||
.path(device_path)?
|
.path(device_path)?
|
||||||
|
.cache_properties(zbus::CacheProperties::Yes)
|
||||||
.build()
|
.build()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn foo(device: &DeviceProxy<'static>) {
|
|
||||||
let mut icon_name_stream = device.receive_icon_name_changed().await;
|
|
||||||
let mut battery_level_stream = device.receive_battery_level_changed().await;
|
|
||||||
|
|
||||||
glib::MainContext::default()
|
|
||||||
.spawn(async move { while let Some(evt) = icon_name_stream.next().await {} });
|
|
||||||
|
|
||||||
glib::MainContext::default()
|
|
||||||
.spawn(async move { while let Some(evt) = battery_level_stream.next().await {} });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct AppModel {
|
struct AppModel {
|
||||||
icon_name: String,
|
icon_name: String,
|
||||||
battery_percent: u8,
|
battery_percent: f64,
|
||||||
time_remaining: Duration,
|
time_remaining: Duration,
|
||||||
display_brightness: f64,
|
display_brightness: f64,
|
||||||
keyboard_brightness: f64,
|
keyboard_brightness: f64,
|
||||||
|
device: Option<DeviceProxy<'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AppMsg {
|
enum AppMsg {
|
||||||
SetDisplayBrightness(f64),
|
SetDisplayBrightness(f64),
|
||||||
SetKeyboardBrightness(f64),
|
SetKeyboardBrightness(f64),
|
||||||
|
SetDevice(DeviceProxy<'static>),
|
||||||
|
UpdateProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component]
|
#[relm4::component]
|
||||||
|
|
@ -81,8 +74,9 @@ impl SimpleComponent for AppModel {
|
||||||
gtk4::Label {
|
gtk4::Label {
|
||||||
set_halign: gtk4::Align::Start,
|
set_halign: gtk4::Align::Start,
|
||||||
// XXX duration formatting
|
// XXX duration formatting
|
||||||
|
// XXX time to full, fully changed, etc.
|
||||||
#[watch]
|
#[watch]
|
||||||
set_label: &format!("{:?} until empty ({}%)", model.time_remaining, model.battery_percent),
|
set_label: &format!("{:?} until empty ({:.0}%)", model.time_remaining, model.battery_percent),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -188,16 +182,56 @@ impl SimpleComponent for AppModel {
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
let sender = sender.clone();
|
||||||
|
glib::MainContext::default().spawn(async move {
|
||||||
|
match display_device().await {
|
||||||
|
Ok(device) => sender.input(AppMsg::SetDevice(device)),
|
||||||
|
Err(err) => eprintln!("Failed to open UPower display device: {}", err),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Input, _sender: &ComponentSender<Self>) {
|
fn update(&mut self, msg: Self::Input, sender: &ComponentSender<Self>) {
|
||||||
match msg {
|
match msg {
|
||||||
AppMsg::SetDisplayBrightness(value) => {
|
AppMsg::SetDisplayBrightness(value) => {
|
||||||
self.display_brightness = value;
|
self.display_brightness = value;
|
||||||
|
// XXX set brightness
|
||||||
}
|
}
|
||||||
AppMsg::SetKeyboardBrightness(value) => {
|
AppMsg::SetKeyboardBrightness(value) => {
|
||||||
self.keyboard_brightness = value;
|
self.keyboard_brightness = value;
|
||||||
|
// XXX set brightness
|
||||||
|
}
|
||||||
|
AppMsg::SetDevice(device) => {
|
||||||
|
self.device = Some(device.clone());
|
||||||
|
|
||||||
|
let sender = sender.clone();
|
||||||
|
glib::MainContext::default().spawn(async move {
|
||||||
|
let mut stream = futures::stream_select!(
|
||||||
|
device.receive_icon_name_changed().await.map(|_| ()),
|
||||||
|
device.receive_percentage_changed().await.map(|_| ()),
|
||||||
|
device.receive_time_to_empty_changed().await.map(|_| ()),
|
||||||
|
);
|
||||||
|
|
||||||
|
sender.input(AppMsg::UpdateProperties);
|
||||||
|
while let Some(()) = stream.next().await {
|
||||||
|
sender.input(AppMsg::UpdateProperties);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
AppMsg::UpdateProperties => {
|
||||||
|
if let Some(device) = self.device.as_ref() {
|
||||||
|
if let Ok(Some(percentage)) = device.cached_percentage() {
|
||||||
|
self.battery_percent = percentage;
|
||||||
|
}
|
||||||
|
if let Ok(Some(icon_name)) = device.cached_icon_name() {
|
||||||
|
self.icon_name = icon_name;
|
||||||
|
}
|
||||||
|
if let Ok(Some(secs)) = device.cached_time_to_empty() {
|
||||||
|
self.time_remaining = Duration::from_secs(secs as u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
use zbus::dbus_proxy;
|
use zbus::dbus_proxy;
|
||||||
|
|
||||||
#[dbus_proxy(interface = "org.freedesktop.UPower")]
|
#[dbus_proxy(
|
||||||
|
default_service = "org.freedesktop.UPower",
|
||||||
|
interface = "org.freedesktop.UPower"
|
||||||
|
)]
|
||||||
trait UPower {
|
trait UPower {
|
||||||
/// EnumerateDevices method
|
/// EnumerateDevices method
|
||||||
fn enumerate_devices(&self) -> zbus::Result<Vec<zbus::zvariant::OwnedObjectPath>>;
|
fn enumerate_devices(&self) -> zbus::Result<Vec<zbus::zvariant::OwnedObjectPath>>;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
use zbus::dbus_proxy;
|
use zbus::dbus_proxy;
|
||||||
|
|
||||||
#[dbus_proxy(interface = "org.freedesktop.UPower.Device")]
|
#[dbus_proxy(
|
||||||
|
default_service = "org.freedesktop.UPower",
|
||||||
|
interface = "org.freedesktop.UPower.Device"
|
||||||
|
)]
|
||||||
trait Device {
|
trait Device {
|
||||||
/// GetHistory method
|
/// GetHistory method
|
||||||
fn get_history(
|
fn get_history(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue