fix: hide the charge limit toggle on unsupported devices

This commit is contained in:
Ashley Wulber 2025-07-28 13:53:51 -04:00 committed by Ashley Wulber
parent 98e1cdec52
commit 65b8376a40
4 changed files with 67 additions and 47 deletions

1
Cargo.lock generated
View file

@ -1087,6 +1087,7 @@ dependencies = [
name = "cosmic-applet-battery"
version = "0.1.0"
dependencies = [
"anyhow",
"cosmic-settings-subscriptions",
"cosmic-time",
"drm 0.14.1",

View file

@ -5,6 +5,7 @@ edition = "2021"
license = "GPL-3.0-only"
[dependencies]
anyhow = "1"
cosmic-settings-subscriptions.workspace = true
cosmic-settings-subscriptions.features = ["settings_daemon", "upower"]
cosmic-time.workspace = true

View file

@ -25,7 +25,6 @@ use cosmic::{
window, Length, Subscription,
},
iced_core::{Alignment, Background, Border, Color, Shadow},
iced_runtime::core::layout::Limits,
iced_widget::{Column, Row},
surface, theme,
widget::{divider, horizontal_space, icon, scrollable, text, vertical_space},
@ -80,7 +79,7 @@ struct CosmicBatteryApplet {
core: cosmic::app::Core,
icon_name: String,
display_icon_name: String,
charging_limit: bool,
charging_limit: Option<bool>,
battery_percent: f64,
on_battery: bool,
gpus: HashMap<PathBuf, GPUData>,
@ -106,26 +105,31 @@ impl CosmicBatteryApplet {
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 {
100
} else if self.battery_percent > 80.0 && !self.charging_limit {
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
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 {
0
""
};
let limited = if self.charging_limit { "limited-" } else { "" };
let charging = if on_battery { "" } else { "charging-" };
self.icon_name =
format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",);
@ -159,7 +163,7 @@ impl CosmicBatteryApplet {
}
fn set_charging_limit(&mut self, limit: bool) {
self.charging_limit = limit;
self.charging_limit = Some(limit);
self.update_battery(self.battery_percent, self.on_battery);
}
}
@ -174,7 +178,7 @@ enum Message {
SetKbdBrightnessDebounced,
SetScreenBrightnessDebounced,
ReleaseScreenBrightness,
InitChargingLimit(bool),
InitChargingLimit(Option<bool>),
SetChargingLimit(chain::Toggler, bool),
KeyboardBacklight(KeyboardBacklightUpdate),
UpowerDevice(DeviceDbusEvent),
@ -204,7 +208,7 @@ impl cosmic::Application for CosmicBatteryApplet {
cosmic::Action::App(Message::ZbusConnection(res))
});
let init_charging_limit_cmd = Task::perform(get_charging_limit(), |limit| {
cosmic::Action::App(Message::InitChargingLimit(limit))
cosmic::Action::App(Message::InitChargingLimit(limit.ok()))
});
(
Self {
@ -294,7 +298,9 @@ impl cosmic::Application for CosmicBatteryApplet {
}
}
Message::InitChargingLimit(enable) => {
self.set_charging_limit(enable);
if let Some(enable) = enable {
self.set_charging_limit(enable);
}
}
Message::SetChargingLimit(chain, enable) => {
self.timeline.set_chain(chain).start();
@ -324,7 +330,7 @@ impl cosmic::Application for CosmicBatteryApplet {
let new_id = window::Id::unique();
self.popup.replace(new_id);
let mut popup_settings = self.core.applet.get_popup_settings(
let popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
new_id,
Some((1, 1)),
@ -334,7 +340,14 @@ impl cosmic::Application for CosmicBatteryApplet {
if let Some(tx) = self.power_profile_sender.as_ref() {
let _ = tx.send(PowerProfileRequest::Get);
}
return get_popup(popup_settings);
let mut tasks = vec![get_popup(popup_settings)];
// Try again every time a popup is opened
if self.charging_limit.is_none() {
tasks.push(Task::perform(get_charging_limit(), |limit| {
cosmic::Action::App(Message::InitChargingLimit(limit.ok()))
}));
}
return Task::batch(tasks);
}
}
Message::UpowerDevice(event) => match event {
@ -601,24 +614,31 @@ impl cosmic::Application for CosmicBatteryApplet {
padded_control(divider::horizontal::default())
.padding([space_xxs, space_s])
.into(),
padded_control(
anim!(
//toggler
MAX_CHARGE,
&self.timeline,
fl!("max-charge"),
self.charging_limit,
Message::SetChargingLimit,
)
.text_size(14)
.width(Length::Fill),
)
.into(),
padded_control(divider::horizontal::default())
.padding([space_xxs, space_s])
.into(),
];
if let Some(charging_limit) = self.charging_limit {
content.push(
padded_control(
anim!(
//toggler
MAX_CHARGE,
&self.timeline,
fl!("max-charge"),
charging_limit,
Message::SetChargingLimit,
)
.text_size(14)
.width(Length::Fill),
)
.into(),
);
content.push(
padded_control(divider::horizontal::default())
.padding([space_xxs, space_s])
.into(),
);
}
if let Some(max_screen_brightness) = self.max_screen_brightness {
if let Some(screen_brightness) = self.screen_brightness {
content.push(

View file

@ -214,24 +214,22 @@ pub enum PowerProfileUpdate {
}
// check if battery charging thresholds is set
pub async fn get_charging_limit() -> bool {
pub async fn get_charging_limit() -> anyhow::Result<bool> {
if let Ok(conn) = Connection::system().await {
if let Ok(backend) = get_power_backend(&conn, &BackendType::S76PowerDaemon).await {
match backend {
Backend::S76PowerDaemon(proxy) => {
if let Ok((start, end)) = proxy.get_charge_thresholds().await {
return start > 0 || end > 0;
return Ok(start > 0 || end > 0);
}
}
Backend::PowerProfilesDaemon(_) => {
tracing::info!("Power Profiles Daemon is not supported.");
return false;
}
};
}
}
false
anyhow::bail!("Unsupported")
}
// set battery charging thresholds via s76 power_daemon