fix: battery icon
This commit is contained in:
parent
9dda03ca3d
commit
0272e189f4
6 changed files with 108 additions and 35 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -1103,7 +1103,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-applets-config"
|
||||
version = "1.0.2"
|
||||
source = "git+https://github.com/pop-os/cosmic-applets?branch=iced-rebase#7db8b111ae3f6e82957292a737ea836ac575e9b5"
|
||||
source = "git+https://github.com/pop-os/cosmic-applets#a91fc32edb63011d5cf3e4fec55990386dfb35a5"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"serde",
|
||||
|
|
@ -1112,7 +1112,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-bg-config"
|
||||
version = "1.0.3"
|
||||
source = "git+https://github.com/pop-os/cosmic-bg?branch=iced-rebase#80ec0e08ef51ce28dc4f9b61b8bb5cddb32c3a07"
|
||||
source = "git+https://github.com/pop-os/cosmic-bg#644993abd84bf04d7b3f2211e3656002c2a6f00b"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"derive_setters",
|
||||
|
|
@ -1137,7 +1137,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-comp-config"
|
||||
version = "1.0.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp?branch=iced-rebase#e7843332b34b430ae2f1e6c0570bfd82bea767d5"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp#b28a435b18a3c1a8dfb8dbf781b40610aca03604"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"cosmic-randr-shell",
|
||||
|
|
@ -1375,7 +1375,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-settings-daemon-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-settings-daemon?branch=iced-rebase#4e98c993f7284e5f565fdd1385c51f9ce1084d91"
|
||||
source = "git+https://github.com/pop-os/cosmic-settings-daemon#e37160f14d1e7ee428f973cd2848b4e95f83dfe1"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"cosmic-theme",
|
||||
|
|
|
|||
10
Cargo.toml
10
Cargo.toml
|
|
@ -52,7 +52,7 @@ cosmic-settings-accessibility-subscription = { git = "https://github.com/pop-os/
|
|||
cosmic-settings-a11y-manager-subscription = { git = "https://github.com/pop-os/cosmic-settings", default-features = false, branch = "iced-rebase" }
|
||||
cosmic-settings-daemon-config = { git = "https://github.com/pop-os/cosmic-settings-daemon", default-features = false, features = [
|
||||
"greeter",
|
||||
], branch = "iced-rebase" }
|
||||
] }
|
||||
|
||||
cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit" }
|
||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [
|
||||
|
|
@ -136,20 +136,14 @@ cosmic-randr-shell = { git = "https://github.com/pop-os/cosmic-randr", default-f
|
|||
|
||||
[workspace.dependencies.cosmic-applets-config]
|
||||
git = "https://github.com/pop-os/cosmic-applets"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-applets/cosmic-applets-config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-bg-config]
|
||||
git = "https://github.com/pop-os/cosmic-bg"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-bg/config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-comp-config]
|
||||
git = "https://github.com/pop-os/cosmic-comp"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-comp/cosmic-comp-config"
|
||||
default-features = false
|
||||
features = ["output", "randr"]
|
||||
|
||||
|
|
@ -158,12 +152,10 @@ path = "cosmic-greeter-config"
|
|||
|
||||
[workspace.dependencies.cosmic-config]
|
||||
git = "https://github.com/pop-os/libcosmic"
|
||||
# path = "../libcosmic/cosmic-config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-theme]
|
||||
git = "https://github.com/pop-os/libcosmic"
|
||||
# path = "../libcosmic/cosmic-theme"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.libcosmic]
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ pub struct ActiveLayout {
|
|||
pub struct Common<M> {
|
||||
pub active_layouts: Vec<ActiveLayout>,
|
||||
pub active_surface_id_opt: Option<SurfaceId>,
|
||||
pub on_battery: bool,
|
||||
pub battery_percent: f64,
|
||||
pub charging_limit: Option<bool>,
|
||||
pub caps_lock: bool,
|
||||
pub comp_config_handler: Option<cosmic_config::Config>,
|
||||
pub core: Core,
|
||||
|
|
@ -57,7 +60,7 @@ pub enum Message {
|
|||
Key(Modifiers, Key, Option<SmolStr>),
|
||||
NetworkIcon(Option<&'static str>),
|
||||
OutputEvent(OutputEvent, WlOutput),
|
||||
PowerInfo(Option<(String, f64)>),
|
||||
PowerInfo(Option<(f64, bool, bool)>),
|
||||
Prompt(String, bool, Option<String>),
|
||||
SessionLockEvent(SessionLockEvent),
|
||||
Tick,
|
||||
|
|
@ -117,6 +120,9 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
text_input_ids: HashMap::new(),
|
||||
time: crate::time::Time::new(),
|
||||
window_size: HashMap::new(),
|
||||
battery_percent: 0.0,
|
||||
on_battery: false,
|
||||
charging_limit: None,
|
||||
};
|
||||
(
|
||||
app,
|
||||
|
|
@ -292,8 +298,11 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
}
|
||||
}
|
||||
Message::PowerInfo(power_info_opt) => {
|
||||
self.power_info_opt = power_info_opt
|
||||
.map(|(name, level)| (widget::icon::from_name(name).into(), level));
|
||||
if let Some((level, on_battery, threshold_enabled)) = power_info_opt {
|
||||
tracing::error!("power level: {}", level);
|
||||
self.charging_limit = Some(threshold_enabled);
|
||||
self.update_battery(level, on_battery);
|
||||
}
|
||||
}
|
||||
Message::Prompt(prompt, secret, value_opt) => {
|
||||
let prompt_was_none = self.prompt_opt.is_none();
|
||||
|
|
@ -370,3 +379,44 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
Subscription::batch(subscriptions)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Common<M> {
|
||||
fn update_battery(&mut self, mut percent: f64, on_battery: bool) {
|
||||
percent = percent.clamp(0.0, 100.0);
|
||||
self.on_battery = on_battery;
|
||||
self.battery_percent = percent;
|
||||
let battery_percent =
|
||||
if self.battery_percent > 95.0 && !self.charging_limit.unwrap_or_default() {
|
||||
100
|
||||
} else if self.battery_percent > 80.0 && !self.charging_limit.unwrap_or_default() {
|
||||
90
|
||||
} else if self.battery_percent > 65.0 {
|
||||
80
|
||||
} else if self.battery_percent > 35.0 {
|
||||
50
|
||||
} else if self.battery_percent > 20.0 {
|
||||
35
|
||||
} else if self.battery_percent > 14.0 {
|
||||
20
|
||||
} else if self.battery_percent > 9.0 {
|
||||
10
|
||||
} else if self.battery_percent > 5.0 {
|
||||
5
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let limited = if self.charging_limit.unwrap_or_default() {
|
||||
"limited-"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let charging = if on_battery { "" } else { "charging-" };
|
||||
self.power_info_opt = Some((
|
||||
widget::icon::from_name(format!(
|
||||
"cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",
|
||||
))
|
||||
.into(),
|
||||
percent,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use cosmic::cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity
|
|||
use cosmic::iced::event::listen_with;
|
||||
use cosmic::iced::{Point, Size, window};
|
||||
use cosmic::iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings;
|
||||
use cosmic::iced_runtime::task::widget;
|
||||
use cosmic::widget::text;
|
||||
use cosmic::{
|
||||
Element,
|
||||
|
|
@ -514,10 +513,13 @@ impl App {
|
|||
}
|
||||
|
||||
if let Some((power_icon, power_percent)) = &self.common.power_info_opt {
|
||||
status_row = status_row.push(iced::widget::row![
|
||||
power_icon.clone(),
|
||||
widget::text(format!("{:.0}%", power_percent)),
|
||||
]);
|
||||
status_row = status_row.push(
|
||||
iced::widget::row![
|
||||
power_icon.clone(),
|
||||
widget::text(format!("{:.0}%", power_percent)),
|
||||
]
|
||||
.align_y(Alignment::Center),
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: move code for custom dropdowns to libcosmic
|
||||
|
|
|
|||
|
|
@ -348,10 +348,13 @@ impl App {
|
|||
}
|
||||
|
||||
if let Some((power_icon, power_percent)) = &self.common.power_info_opt {
|
||||
status_row = status_row.push(iced::widget::row![
|
||||
power_icon.clone(),
|
||||
widget::text(format!("{:.0}%", power_percent)),
|
||||
]);
|
||||
status_row = status_row.push(
|
||||
iced::widget::row![
|
||||
power_icon.clone(),
|
||||
widget::text(format!("{:.0}%", power_percent)),
|
||||
]
|
||||
.align_y(Alignment::Center),
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: move code for custom dropdowns to libcosmic
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ use cosmic::iced::{
|
|||
Subscription,
|
||||
futures::{SinkExt, StreamExt, channel::mpsc},
|
||||
};
|
||||
use futures_util::select;
|
||||
use std::{any::TypeId, time::Duration};
|
||||
use upower_dbus::UPowerProxy;
|
||||
use upower_dbus::{BatteryState, BatteryType, UPowerProxy};
|
||||
use zbus::{Connection, Result};
|
||||
|
||||
pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
||||
pub fn subscription() -> Subscription<Option<(f64, bool, bool)>> {
|
||||
struct PowerSubscription;
|
||||
|
||||
Subscription::run_with(TypeId::of::<PowerSubscription>(), |_| {
|
||||
|
|
@ -29,30 +30,55 @@ pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
|||
}
|
||||
|
||||
//TODO: use never type?
|
||||
pub async fn handler(msg_tx: &mut mpsc::Sender<Option<(String, f64)>>) -> Result<()> {
|
||||
pub async fn handler(msg_tx: &mut mpsc::Sender<Option<(f64, bool, bool)>>) -> 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;
|
||||
let mut percentage_changed = dev.receive_percentage_changed().await.boxed().fuse();
|
||||
let mut state_changed = dev.receive_state_changed().await.boxed().fuse();
|
||||
let mut charge_threshold_enabled_changed = dev
|
||||
.receive_charge_threshold_enabled_changed()
|
||||
.await
|
||||
.boxed()
|
||||
.fuse();
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
let has_battery = dev.type_().await? == BatteryType::Battery && dev.power_supply().await?;
|
||||
if !has_battery {
|
||||
return Ok(());
|
||||
}
|
||||
loop {
|
||||
let mut info_opt = None;
|
||||
|
||||
if let Ok(percent) = dev.percentage().await {
|
||||
if let Ok(icon_name) = dev.icon_name().await {
|
||||
if !icon_name.is_empty() && !icon_name.eq("battery-missing-symbolic") {
|
||||
info_opt = Some((icon_name, percent));
|
||||
if let Ok(mut percent) = dev.percentage().await {
|
||||
if let Ok(state) = dev.state().await {
|
||||
let threshold_enabled = dev.charge_threshold_enabled().await.unwrap_or_default();
|
||||
|
||||
let capacity = dev.capacity().await.unwrap_or(100.);
|
||||
|
||||
// compensate for declining battery capacity
|
||||
percent = percent * 100. / capacity;
|
||||
if matches!(state, BatteryState::FullyCharged) || percent > 100. {
|
||||
percent = 100.;
|
||||
}
|
||||
|
||||
info_opt = Some((
|
||||
percent,
|
||||
state == BatteryState::Discharging,
|
||||
threshold_enabled,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
msg_tx.send(info_opt).await.unwrap();
|
||||
|
||||
// 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;
|
||||
select! {
|
||||
_ = state_changed.next() => {},
|
||||
_ = percentage_changed.next() => {},
|
||||
_ = charge_threshold_enabled_changed.next() => {}
|
||||
}
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue