I think I've got status fetching down; need to test on something with an actual battery

This commit is contained in:
2022-05-04 15:13:34 +02:00
parent 048d3dd700
commit 2d5ed69245
2 changed files with 74 additions and 17 deletions

View File

@@ -74,7 +74,7 @@ impl Surface {
"WattBar".to_owned(),
);
layer_surface.set_size(32, 32);
layer_surface.set_size(1900, 3);
layer_surface.set_anchor(zwlr_layer_surface_v1::Anchor::Bottom);
layer_surface.set_exclusive_zone(3);
let next_render_event = Rc::new(Cell::new(None));
@@ -130,6 +130,9 @@ impl Surface {
}
fn draw(&mut self) {
if self.dimensions.0 == 0 || self.dimensions.1 == 0 {
return;
}
let stride = 4 * self.dimensions.0 as i32;
let width = self.dimensions.0 as i32;
let height = self.dimensions.1 as i32;
@@ -165,14 +168,14 @@ fn main() -> anyhow::Result<()> {
// Spawn upower watcher
let upower_channel = {
let (sender, channel) = calloop::channel::channel();
let reporter = upower::PowerReporter {
sender,
status: Arc::clone(&app_state.display_status),
};
let (sender, channel) = calloop::channel::channel();
let reporter = upower::PowerReporter {
sender,
status: Arc::clone(&app_state.display_status),
};
upower::spawn_upower(reporter)?;
channel
upower::spawn_upower(reporter)?;
channel
};
let (env, display, queue) =
@@ -215,17 +218,20 @@ fn main() -> anyhow::Result<()> {
let mut event_loop = calloop::EventLoop::<()>::try_new().expect("Failed to start event loop");
let surfaces_handle = Rc::clone(&surfaces);
let power_state_handle = Arc::clone(&app_state.display_status);
event_loop.handle().insert_source(
upower_channel,
move |_, _, _| {
for (_, surface) in surfaces_handle.borrow_mut().iter() {
if surface.next_render_event.get().is_none() {
surface.next_render_event.set(Some(RenderEvent::DataChanged));
}
}
}
upower_channel,
move |_, _, _| {
eprintln!("Power state: {:?}", &*power_state_handle.read().unwrap());
for (_, surface) in surfaces_handle.borrow_mut().iter() {
if surface.next_render_event.get().is_none() {
surface.next_render_event.set(Some(RenderEvent::DataChanged));
}
}
}
).unwrap();
WaylandSource::new(queue)
.quick_insert(event_loop.handle())
.unwrap();

View File

@@ -1,3 +1,4 @@
use std::collections::HashMap;
use crate::PowerState;
use std::sync::mpsc::SyncSender;
use std::sync::{
@@ -7,7 +8,9 @@ use std::sync::{
use upower_dbus;
use calloop::channel::Sender as CalloopSender;
use upower_dbus::BatteryState;
use zbus;
use zbus::zvariant::OwnedValue;
pub struct PowerReporter {
pub sender: CalloopSender<()>,
@@ -37,19 +40,67 @@ pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> {
start_receive.recv()?
}
fn upower_update(reporter: &PowerReporter, properties: &HashMap<String, OwnedValue>) {
{
let mut status = reporter.status.write().unwrap();
let battery_state = upower_dbus::BatteryState::try_from(properties["State"].clone()).unwrap();
let charging = match battery_state {
// fully enumerate the options in case a new one is added.
BatteryState::Charging |
BatteryState::FullyCharged |
BatteryState::PendingCharge => true,
BatteryState::Empty |
BatteryState::Discharging |
BatteryState::PendingDischarge |
BatteryState::Unknown => false,
};
*status = Some(PowerState {
level: f64::try_from(&properties["Percentage"]).unwrap() as f32 / 100.0,
charging,
time_remaining: if charging {
i64::try_from(&properties["TimeToFull"]).unwrap()
} else {
i64::try_from(&properties["TimeToEmpty"]).unwrap()
} as f32
})
}
// Notify listeners
reporter.sender.send(()).ok();
}
fn upower_run(
reporter: PowerReporter,
start_send: &SyncSender<anyhow::Result<()>>,
) -> anyhow::Result<()> {
let dbus = zbus::blocking::Connection::system()?;
let display_device_path = upower_dbus::UPowerProxyBlocking::new(&dbus)?.get_display_device()?;
let display_proxy = zbus::blocking::fdo::PropertiesProxy::builder(&dbus)
let display_proxy : zbus::blocking::fdo::PropertiesProxy = zbus::blocking::fdo::PropertiesProxy::builder(&dbus)
.destination("org.freedesktop.UPower")?
.path(display_device_path)?
.cache_properties(zbus::CacheProperties::No)
.build()?;
let mut prop_changed_iterator = display_proxy.receive_properties_changed()?;
let device_interface_name = zbus::names::InterfaceName::from_static_str("org.freedesktop.UPower.Device").unwrap();
let mut properties: HashMap<String, OwnedValue> = display_proxy.get_all(device_interface_name.clone())?;
upower_update(&reporter, &properties);
start_send.send(Ok(())).unwrap();
for signal in prop_changed_iterator {
let args = signal.args().expect("Invalid signal arguments");
if args.interface_name != device_interface_name {
continue
}
for (name, value) in args.changed_properties {
properties.get_mut(name).map(|vp| *vp = value.into());
}
// Update reporter
upower_update(&reporter, &properties);
}
// TODO: actually watch for events
Ok(())