This commit is contained in:
Ashley Wulber 2022-12-05 10:52:48 -05:00
parent 6b25ba5742
commit 93fa346bd8
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
3 changed files with 132 additions and 99 deletions

View file

@ -1,3 +1,12 @@
use crate::backlight::{
screen_backlight_subscription, ScreenBacklightRequest, ScreenBacklightUpdate,
};
use crate::config;
use crate::fl;
use crate::upower_device::{device_subscription, DeviceDbusEvent};
use crate::upower_kbdbacklight::{
kbd_backlight_subscription, KeyboardBacklightRequest, KeyboardBacklightUpdate,
};
use cosmic::applet::{get_popup_settings, icon_button, popup_container}; use cosmic::applet::{get_popup_settings, icon_button, popup_container};
use cosmic::iced::alignment::Horizontal; use cosmic::iced::alignment::Horizontal;
use cosmic::iced::{ use cosmic::iced::{
@ -17,14 +26,9 @@ use iced_sctk::application::SurfaceIdWrapper;
use iced_sctk::command::platform_specific::wayland::window::SctkWindowSettings; use iced_sctk::command::platform_specific::wayland::window::SctkWindowSettings;
use iced_sctk::commands::popup::{destroy_popup, get_popup}; use iced_sctk::commands::popup::{destroy_popup, get_popup};
use iced_sctk::settings::InitialSurface; use iced_sctk::settings::InitialSurface;
use iced_sctk::{Color}; use iced_sctk::Color;
use std::time::Duration; use std::time::Duration;
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
use crate::backlight::{ScreenBacklightRequest, screen_backlight_subscription, ScreenBacklightUpdate};
use crate::config;
use crate::upower_device::{device_subscription, DeviceDbusEvent};
use crate::upower_kbdbacklight::{KeyboardBacklightRequest, kbd_backlight_subscription, KeyboardBacklightUpdate};
use crate::fl;
// XXX improve // XXX improve
// TODO: time to empty varies? needs averaging? // TODO: time to empty varies? needs averaging?
@ -185,22 +189,21 @@ impl Application for CosmicBatteryApplet {
} }
Message::UpdateKbdBrightness(b) => { Message::UpdateKbdBrightness(b) => {
self.kbd_brightness = b; self.kbd_brightness = b;
}, }
Message::Ignore => {}, Message::Ignore => {}
Message::InitKbdBacklight(tx, brightness) => { Message::InitKbdBacklight(tx, brightness) => {
let _ = tx.send(KeyboardBacklightRequest::Get); let _ = tx.send(KeyboardBacklightRequest::Get);
self.kbd_sender = Some(tx); self.kbd_sender = Some(tx);
self.kbd_brightness = brightness; self.kbd_brightness = brightness;
}, }
Message::InitScreenBacklight(tx, brightness) => { Message::InitScreenBacklight(tx, brightness) => {
let _ = tx.send(ScreenBacklightRequest::Get); let _ = tx.send(ScreenBacklightRequest::Get);
self.screen_sender = Some(tx); self.screen_sender = Some(tx);
self.screen_brightness = brightness; self.screen_brightness = brightness;
}
},
Message::UpdateScreenBrightness(b) => { Message::UpdateScreenBrightness(b) => {
self.screen_brightness = b; self.screen_brightness = b;
}, }
} }
Command::none() Command::none()
} }
@ -218,66 +221,92 @@ impl Application for CosmicBatteryApplet {
.into(), .into(),
SurfaceIdWrapper::Popup(_) => { SurfaceIdWrapper::Popup(_) => {
let name = text(fl!("battery")).size(18); let name = text(fl!("battery")).size(18);
let description = text(if "battery-full-charging-symbolic" == self.icon_name || "battery-full-charged-symbolic" == self.icon_name { let description = text(
format!("{}%", self.battery_percent) if "battery-full-charging-symbolic" == self.icon_name
} else { || "battery-full-charged-symbolic" == self.icon_name
format!( {
"{} {} ({:.0}%)", format!("{}%", self.battery_percent)
format_duration(self.time_remaining), } else {
fl!("until-empty"), format!(
self.battery_percent "{} {} ({:.0}%)",
) format_duration(self.time_remaining),
}) fl!("until-empty"),
self.battery_percent
)
},
)
.size(12); .size(12);
popup_container( popup_container(
column![ column![
row![ row![
icon(&self.icon_name, 24) icon(&self.icon_name, 24)
.style(Svg::Custom(|theme| { .style(Svg::Custom(|theme| {
svg::Appearance { svg::Appearance {
fill: Some(theme.palette().text), fill: Some(theme.palette().text),
} }
})) }))
.width(Length::Units(24)) .width(Length::Units(24))
.height(Length::Units(24)), .height(Length::Units(24)),
column![name, description] column![name, description]
] ]
.spacing(8) .spacing(8)
.align_items(Alignment::Center), .align_items(Alignment::Center),
separator!(1), separator!(1),
// text{"Limit Battery Charging"}, // text{"Limit Battery Charging"},
widget::Toggler::new(self.charging_limit, fl!("max-charge"), |_| Message::SetChargingLimit(!self.charging_limit)), widget::Toggler::new(self.charging_limit, fl!("max-charge"), |_| {
Message::SetChargingLimit(!self.charging_limit)
}),
separator!(1), separator!(1),
row![icon("display-brightness-symbolic", 24) row![
.style( icon("display-brightness-symbolic", 24)
Svg::Custom(|theme| { .style(Svg::Custom(|theme| {
svg::Appearance { svg::Appearance {
fill: Some(theme.palette().text), fill: Some(theme.palette().text),
} }
})) }))
.width(Length::Units(24)) .width(Length::Units(24))
.height(Length::Units(24)), .height(Length::Units(24)),
widget::slider(0..=100, (self.screen_brightness * 100.0) as i32, Message::SetScreenBrightness), widget::slider(
text(format!("{:.0}%", self.screen_brightness * 100.0)).width(Length::Units(40)).horizontal_alignment(Horizontal::Right) 0..=100,
].spacing(12), (self.screen_brightness * 100.0) as i32,
Message::SetScreenBrightness
),
text(format!("{:.0}%", self.screen_brightness * 100.0))
.width(Length::Units(40))
.horizontal_alignment(Horizontal::Right)
]
.spacing(12),
row![ row![
icon("keyboard-brightness-symbolic", 24) icon("keyboard-brightness-symbolic", 24)
.style(Svg::Custom(|theme| { .style(Svg::Custom(|theme| {
svg::Appearance { svg::Appearance {
fill: Some(theme.palette().text), fill: Some(theme.palette().text),
} }
})) }))
.width(Length::Units(24)) .width(Length::Units(24))
.height(Length::Units(24)), .height(Length::Units(24)),
widget::slider(0..=100, (self.kbd_brightness * 100.0) as i32, Message::SetKbdBrightness), widget::slider(
text(format!("{:.0}%", self.kbd_brightness * 100.0)).width(Length::Units(40)).horizontal_alignment(Horizontal::Right) 0..=100,
].spacing(12), (self.kbd_brightness * 100.0) as i32,
button(text(fl!("power-settings")).horizontal_alignment(Horizontal::Center).width(Length::Fill).style(theme::Text::Custom(|theme| { Message::SetKbdBrightness
let cosmic = theme.cosmic(); ),
iced_style::text::Appearance { text(format!("{:.0}%", self.kbd_brightness * 100.0))
color: Some(cosmic.accent.on.into()) .width(Length::Units(40))
} .horizontal_alignment(Horizontal::Right)
}))).width(Length::Fill) ]
.spacing(12),
button(
text(fl!("power-settings"))
.horizontal_alignment(Horizontal::Center)
.width(Length::Fill)
.style(theme::Text::Custom(|theme| {
let cosmic = theme.cosmic();
iced_style::text::Appearance {
color: Some(cosmic.accent.on.into()),
}
}))
)
.width(Length::Fill)
] ]
.spacing(4) .spacing(4)
.padding(8), .padding(8),
@ -307,9 +336,8 @@ impl Application for CosmicBatteryApplet {
screen_backlight_subscription(0).map(|(_, event)| match event { screen_backlight_subscription(0).map(|(_, event)| match event {
ScreenBacklightUpdate::Update(b) => Message::UpdateScreenBrightness(b), ScreenBacklightUpdate::Update(b) => Message::UpdateScreenBrightness(b),
ScreenBacklightUpdate::Init(tx, b) => Message::InitScreenBacklight(tx, b), ScreenBacklightUpdate::Init(tx, b) => Message::InitScreenBacklight(tx, b),
}) }),
]) ])
} }
fn theme(&self) -> Theme { fn theme(&self) -> Theme {

View file

@ -1,7 +1,7 @@
#[rustfmt::skip] #[rustfmt::skip]
mod backlight; mod backlight;
mod config;
mod app; mod app;
mod config;
mod localize; mod localize;
mod power_daemon; mod power_daemon;
mod upower; mod upower;

View file

@ -5,9 +5,9 @@
use cosmic::iced; use cosmic::iced;
use iced::subscription; use iced::subscription;
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel};
use zbus::dbus_proxy;
use std::{fmt::Debug, hash::Hash}; use std::{fmt::Debug, hash::Hash};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use zbus::dbus_proxy;
#[dbus_proxy( #[dbus_proxy(
default_service = "org.freedesktop.UPower", default_service = "org.freedesktop.UPower",
interface = "org.freedesktop.UPower.KbdBacklight", interface = "org.freedesktop.UPower.KbdBacklight",
@ -41,11 +41,17 @@ pub fn kbd_backlight_subscription<I: 'static + Hash + Copy + Send + Sync + Debug
#[derive(Debug)] #[derive(Debug)]
pub enum State { pub enum State {
Ready, Ready,
Waiting(KbdBacklightProxy<'static>, UnboundedReceiver<KeyboardBacklightRequest>), Waiting(
KbdBacklightProxy<'static>,
UnboundedReceiver<KeyboardBacklightRequest>,
),
Finished, Finished,
} }
async fn start_listening<I: Copy>(id: I, state: State) -> (Option<(I, KeyboardBacklightUpdate)>, State) { async fn start_listening<I: Copy>(
id: I,
state: State,
) -> (Option<(I, KeyboardBacklightUpdate)>, State) {
match state { match state {
State::Ready => { State::Ready => {
let conn = match zbus::Connection::system().await { let conn = match zbus::Connection::system().await {
@ -61,38 +67,37 @@ async fn start_listening<I: Copy>(id: I, state: State) -> (Option<(I, KeyboardBa
return ( return (
Some(( Some((
id, id,
KeyboardBacklightUpdate::Init(tx, kbd_proxy.get_brightness().await.unwrap_or_default() as f64) KeyboardBacklightUpdate::Init(
tx,
kbd_proxy.get_brightness().await.unwrap_or_default() as f64,
),
)), )),
State::Waiting(kbd_proxy, rx), State::Waiting(kbd_proxy, rx),
); );
}
State::Waiting(proxy, mut rx) => match rx.recv().await {
Some(req) => match req {
KeyboardBacklightRequest::Get => (
Some((
id,
KeyboardBacklightUpdate::Update(
proxy.get_brightness().await.unwrap_or_default() as f64,
),
)),
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;
}
} (None, State::Waiting(proxy, rx))
State::Waiting(proxy, mut rx) => { }
match rx.recv().await { },
Some(req) => match req { None => (None, State::Finished),
KeyboardBacklightRequest::Get => ( },
Some((
id,
KeyboardBacklightUpdate::Update(proxy.get_brightness().await.unwrap_or_default() as f64)
)),
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;
}
(
None,
State::Waiting(proxy, rx),
)
},
},
None => (None, State::Finished),
}
}
State::Finished => iced::futures::future::pending().await, State::Finished => iced::futures::future::pending().await,
} }
} }
@ -100,7 +105,7 @@ async fn start_listening<I: Copy>(id: I, state: State) -> (Option<(I, KeyboardBa
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum KeyboardBacklightUpdate { pub enum KeyboardBacklightUpdate {
Update(f64), Update(f64),
Init(UnboundedSender<KeyboardBacklightRequest>, f64) Init(UnboundedSender<KeyboardBacklightRequest>, f64),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]