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" name = "cosmic-applet-battery"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"cosmic-settings-subscriptions", "cosmic-settings-subscriptions",
"cosmic-time", "cosmic-time",
"drm 0.14.1", "drm 0.14.1",

View file

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

View file

@ -25,7 +25,6 @@ use cosmic::{
window, Length, Subscription, window, Length, Subscription,
}, },
iced_core::{Alignment, Background, Border, Color, Shadow}, iced_core::{Alignment, Background, Border, Color, Shadow},
iced_runtime::core::layout::Limits,
iced_widget::{Column, Row}, iced_widget::{Column, Row},
surface, theme, surface, theme,
widget::{divider, horizontal_space, icon, scrollable, text, vertical_space}, widget::{divider, horizontal_space, icon, scrollable, text, vertical_space},
@ -80,7 +79,7 @@ struct CosmicBatteryApplet {
core: cosmic::app::Core, core: cosmic::app::Core,
icon_name: String, icon_name: String,
display_icon_name: String, display_icon_name: String,
charging_limit: bool, charging_limit: Option<bool>,
battery_percent: f64, battery_percent: f64,
on_battery: bool, on_battery: bool,
gpus: HashMap<PathBuf, GPUData>, gpus: HashMap<PathBuf, GPUData>,
@ -106,26 +105,31 @@ impl CosmicBatteryApplet {
percent = percent.clamp(0.0, 100.0); percent = percent.clamp(0.0, 100.0);
self.on_battery = on_battery; self.on_battery = on_battery;
self.battery_percent = percent; self.battery_percent = percent;
let battery_percent = if self.battery_percent > 95.0 && !self.charging_limit { let battery_percent =
100 if self.battery_percent > 95.0 && !self.charging_limit.unwrap_or_default() {
} else if self.battery_percent > 80.0 && !self.charging_limit { 100
90 } else if self.battery_percent > 80.0 && !self.charging_limit.unwrap_or_default() {
} else if self.battery_percent > 65.0 { 90
80 } else if self.battery_percent > 65.0 {
} else if self.battery_percent > 35.0 { 80
50 } else if self.battery_percent > 35.0 {
} else if self.battery_percent > 20.0 { 50
35 } else if self.battery_percent > 20.0 {
} else if self.battery_percent > 14.0 { 35
20 } else if self.battery_percent > 14.0 {
} else if self.battery_percent > 9.0 { 20
10 } else if self.battery_percent > 9.0 {
} else if self.battery_percent > 5.0 { 10
5 } else if self.battery_percent > 5.0 {
5
} else {
0
};
let limited = if self.charging_limit.unwrap_or_default() {
"limited-"
} else { } else {
0 ""
}; };
let limited = if self.charging_limit { "limited-" } else { "" };
let charging = if on_battery { "" } else { "charging-" }; let charging = if on_battery { "" } else { "charging-" };
self.icon_name = self.icon_name =
format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",); format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",);
@ -159,7 +163,7 @@ impl CosmicBatteryApplet {
} }
fn set_charging_limit(&mut self, limit: bool) { 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); self.update_battery(self.battery_percent, self.on_battery);
} }
} }
@ -174,7 +178,7 @@ enum Message {
SetKbdBrightnessDebounced, SetKbdBrightnessDebounced,
SetScreenBrightnessDebounced, SetScreenBrightnessDebounced,
ReleaseScreenBrightness, ReleaseScreenBrightness,
InitChargingLimit(bool), InitChargingLimit(Option<bool>),
SetChargingLimit(chain::Toggler, bool), SetChargingLimit(chain::Toggler, bool),
KeyboardBacklight(KeyboardBacklightUpdate), KeyboardBacklight(KeyboardBacklightUpdate),
UpowerDevice(DeviceDbusEvent), UpowerDevice(DeviceDbusEvent),
@ -204,7 +208,7 @@ impl cosmic::Application for CosmicBatteryApplet {
cosmic::Action::App(Message::ZbusConnection(res)) cosmic::Action::App(Message::ZbusConnection(res))
}); });
let init_charging_limit_cmd = Task::perform(get_charging_limit(), |limit| { 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 { Self {
@ -294,7 +298,9 @@ impl cosmic::Application for CosmicBatteryApplet {
} }
} }
Message::InitChargingLimit(enable) => { Message::InitChargingLimit(enable) => {
self.set_charging_limit(enable); if let Some(enable) = enable {
self.set_charging_limit(enable);
}
} }
Message::SetChargingLimit(chain, enable) => { Message::SetChargingLimit(chain, enable) => {
self.timeline.set_chain(chain).start(); self.timeline.set_chain(chain).start();
@ -324,7 +330,7 @@ impl cosmic::Application for CosmicBatteryApplet {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); 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(), self.core.main_window_id().unwrap(),
new_id, new_id,
Some((1, 1)), Some((1, 1)),
@ -334,7 +340,14 @@ impl cosmic::Application for CosmicBatteryApplet {
if let Some(tx) = self.power_profile_sender.as_ref() { if let Some(tx) = self.power_profile_sender.as_ref() {
let _ = tx.send(PowerProfileRequest::Get); 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 { Message::UpowerDevice(event) => match event {
@ -601,24 +614,31 @@ impl cosmic::Application for CosmicBatteryApplet {
padded_control(divider::horizontal::default()) padded_control(divider::horizontal::default())
.padding([space_xxs, space_s]) .padding([space_xxs, space_s])
.into(), .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(max_screen_brightness) = self.max_screen_brightness {
if let Some(screen_brightness) = self.screen_brightness { if let Some(screen_brightness) = self.screen_brightness {
content.push( content.push(

View file

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