feat: add power setttings page, with power profiles
This commit is contained in:
parent
71c776e0f7
commit
1b3d00ebfc
6 changed files with 255 additions and 2 deletions
|
|
@ -11,10 +11,11 @@ use crate::pages::desktop::{
|
|||
},
|
||||
};
|
||||
use crate::pages::input::{self};
|
||||
use crate::pages::{self, display, sound, system, time};
|
||||
use crate::pages::{self, display, power, sound, system, time};
|
||||
use crate::subscription::desktop_files;
|
||||
use crate::widget::{page_title, search_header};
|
||||
use crate::PageCommands;
|
||||
use cosmic::app::command::message;
|
||||
use cosmic::app::DbusActivationMessage;
|
||||
use cosmic::iced::futures::SinkExt;
|
||||
use cosmic::iced::Subscription;
|
||||
|
|
@ -63,7 +64,7 @@ impl SettingsApp {
|
|||
PageCommands::Keyboard => self.pages.page_id::<input::keyboard::Page>(),
|
||||
PageCommands::Mouse => self.pages.page_id::<input::mouse::Page>(),
|
||||
PageCommands::Network => None,
|
||||
PageCommands::Power => None,
|
||||
PageCommands::Power => self.pages.page_id::<power::Page>(),
|
||||
PageCommands::RegionLanguage => self.pages.page_id::<time::region::Page>(),
|
||||
PageCommands::Sound => self.pages.page_id::<sound::Page>(),
|
||||
PageCommands::Time => self.pages.page_id::<time::Page>(),
|
||||
|
|
@ -129,6 +130,7 @@ impl cosmic::Application for SettingsApp {
|
|||
app.insert_page::<sound::Page>();
|
||||
app.insert_page::<system::Page>();
|
||||
app.insert_page::<time::Page>();
|
||||
app.insert_page::<power::Page>();
|
||||
|
||||
let active_id = match flags.subcommand {
|
||||
Some(p) => app.subcommand_to_page(&p),
|
||||
|
|
@ -365,6 +367,10 @@ impl cosmic::Application for SettingsApp {
|
|||
return page.update(message).map(cosmic::app::Message::App);
|
||||
}
|
||||
}
|
||||
|
||||
crate::pages::Message::Power(message) => {
|
||||
page::update!(self.pages, message, power::Page)
|
||||
}
|
||||
},
|
||||
|
||||
Message::PanelConfig(config) if config.name.to_lowercase().contains("panel") => {
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ pub mod networking;
|
|||
pub mod sound;
|
||||
pub mod system;
|
||||
pub mod time;
|
||||
pub mod power;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
About(system::about::Message),
|
||||
Appearance(desktop::appearance::Message),
|
||||
DateAndTime(time::date::Message),
|
||||
Power(power::Message),
|
||||
Desktop(desktop::Message),
|
||||
DesktopWallpaper(desktop::wallpaper::Message),
|
||||
DesktopWorkspaces(desktop::workspaces::Message),
|
||||
|
|
|
|||
108
cosmic-settings/src/pages/power/backend/mod.rs
Normal file
108
cosmic-settings/src/pages/power/backend/mod.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
use zbus::Connection;
|
||||
mod s76powerdaemon;
|
||||
|
||||
// Get backend, if exist s76powerdaemon preferred. If not exist power profiles deamon preferred.
|
||||
async fn get_power_daemon<'a>() -> Result<s76powerdaemon::PowerDaemonProxy<'a>, ()> {
|
||||
let connection = match Connection::system().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!("[Cosmic Settings] zbus connection failed. {e}");
|
||||
return Err(());
|
||||
}
|
||||
};
|
||||
|
||||
match s76powerdaemon::PowerDaemonProxy::new(&connection).await {
|
||||
Ok(d) => Ok(d),
|
||||
Err(e) => {
|
||||
println!("[S76PowerDaemon] Power daemon proxy can't created. Is it installed? {e}");
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum PowerProfile {
|
||||
Performance,
|
||||
Balanced,
|
||||
Battery,
|
||||
}
|
||||
|
||||
impl PowerProfile {
|
||||
fn from_string(s: &str) -> PowerProfile {
|
||||
match s {
|
||||
"Performance" => Self::Performance,
|
||||
"Battery" => Self::Battery,
|
||||
_ => Self::Balanced,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn title(&self) -> String {
|
||||
match self {
|
||||
Self::Performance => fl!("power-profiles", "performance"),
|
||||
Self::Balanced => fl!("power-profiles", "balanced"),
|
||||
Self::Battery => fl!("power-profiles", "battery"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> String {
|
||||
match self {
|
||||
Self::Performance => fl!("power-profiles", "performance-desc"),
|
||||
Self::Balanced => fl!("power-profiles", "balanced-desc"),
|
||||
Self::Battery => fl!("power-profiles", "battery-desc"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn set_power_profile(profile: PowerProfile) {
|
||||
let daemon = match get_power_daemon().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!("[Cosmic Settings] Problem while setting power profile.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match profile {
|
||||
PowerProfile::Performance => match daemon.performance().await {
|
||||
Ok(x) => println!("[Cosmic Settings] Performance mode activated."),
|
||||
Err(e) => println!("{e}"),
|
||||
},
|
||||
PowerProfile::Balanced => match daemon.balanced().await {
|
||||
Ok(x) => println!("[Cosmic Settings] Balanced mode activated."),
|
||||
Err(e) => println!("{e}"),
|
||||
},
|
||||
PowerProfile::Battery => match daemon.battery().await {
|
||||
Ok(x) => println!("[Cosmic Settings] Battery mode activated."),
|
||||
Err(e) => println!("{e}"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_power_profiles() -> Vec<PowerProfile> {
|
||||
vec![
|
||||
PowerProfile::Performance,
|
||||
PowerProfile::Balanced,
|
||||
PowerProfile::Battery,
|
||||
]
|
||||
}
|
||||
|
||||
pub async fn get_current_power_profile() -> PowerProfile {
|
||||
let daemon = match get_power_daemon().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!("[Cosmic Settings] Problem while setting power profile.");
|
||||
//Default
|
||||
return PowerProfile::Balanced;
|
||||
}
|
||||
};
|
||||
|
||||
match daemon.get_profile().await {
|
||||
Ok(p) => PowerProfile::from_string(p.as_str()),
|
||||
//Default
|
||||
Err(_) => {
|
||||
println!("[Cosmic Settings] Problem while setting power profile.");
|
||||
//Default
|
||||
PowerProfile::Balanced
|
||||
}
|
||||
}
|
||||
}
|
||||
41
cosmic-settings/src/pages/power/backend/s76powerdaemon.rs
Normal file
41
cosmic-settings/src/pages/power/backend/s76powerdaemon.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use zbus::proxy;
|
||||
|
||||
#[proxy(
|
||||
interface = "com.system76.PowerDaemon",
|
||||
default_path = "/com/system76/PowerDaemon",
|
||||
assume_defaults = true
|
||||
)]
|
||||
pub trait PowerDaemon {
|
||||
fn balanced(&self) -> zbus::Result<()>;
|
||||
|
||||
fn battery(&self) -> zbus::Result<()>;
|
||||
|
||||
fn get_charge_profiles(
|
||||
&self,
|
||||
) -> zbus::Result<Vec<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>>;
|
||||
|
||||
fn get_charge_thresholds(&self) -> zbus::Result<(u8, u8)>;
|
||||
|
||||
fn get_default_graphics(&self) -> zbus::Result<String>;
|
||||
|
||||
fn get_external_displays_require_dgpu(&self) -> zbus::Result<bool>;
|
||||
|
||||
fn get_graphics(&self) -> zbus::Result<String>;
|
||||
|
||||
fn get_graphics_power(&self) -> zbus::Result<bool>;
|
||||
|
||||
fn get_profile(&self) -> zbus::Result<String>;
|
||||
|
||||
fn get_switchable(&self) -> zbus::Result<bool>;
|
||||
|
||||
fn performance(&self) -> zbus::Result<()>;
|
||||
|
||||
fn set_charge_thresholds(&self, thresholds: &(u8, u8)) -> zbus::Result<()>;
|
||||
|
||||
fn set_graphics(&self, vendor: &str) -> zbus::Result<()>;
|
||||
|
||||
fn set_graphics_power(&self, power: bool) -> zbus::Result<()>;
|
||||
|
||||
#[zbus(signal)]
|
||||
fn hot_plug_detect(&self, port: u64) -> zbus::Result<()>;
|
||||
}
|
||||
83
cosmic-settings/src/pages/power/mod.rs
Normal file
83
cosmic-settings/src/pages/power/mod.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use backend::PowerProfile;
|
||||
use cosmic::iced::widget;
|
||||
use cosmic::{widget::settings, Apply};
|
||||
use slotmap::SlotMap;
|
||||
|
||||
pub mod backend;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Page;
|
||||
|
||||
impl page::Page<crate::pages::Message> for Page {
|
||||
fn info(&self) -> page::Info {
|
||||
page::Info::new("power", "battery-symbolic")
|
||||
.title(fl!("power"))
|
||||
.description(fl!("power", "desc"))
|
||||
}
|
||||
|
||||
fn content(
|
||||
&self,
|
||||
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
|
||||
) -> Option<page::Content> {
|
||||
Some(vec![sections.insert(profiles())])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
PowerProfileChange(PowerProfile),
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub fn update(&mut self, message: Message) {
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
match message {
|
||||
Message::PowerProfileChange(p) => runtime.block_on(backend::set_power_profile(p)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn profiles() -> Section<crate::pages::Message> {
|
||||
Section::default()
|
||||
.title(fl!("power-profiles"))
|
||||
.descriptions(vec![fl!("power", "desc").into()])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
let profiles = backend::get_power_profiles();
|
||||
|
||||
let current_profile = runtime.block_on(backend::get_current_power_profile());
|
||||
|
||||
let mut section = settings::view_section(§ion.title);
|
||||
|
||||
let mut widgets = Vec::new();
|
||||
|
||||
for profile in profiles {
|
||||
let selected = if current_profile == profile {
|
||||
Some(true)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let widget = widget::Radio::new("", true, selected, |_| {
|
||||
Message::PowerProfileChange(profile.clone())
|
||||
});
|
||||
let item = settings::item::builder(profile.title())
|
||||
.description(profile.description())
|
||||
.control(widget);
|
||||
widgets.push(item);
|
||||
}
|
||||
|
||||
for item in widgets {
|
||||
section = section.add(item);
|
||||
}
|
||||
|
||||
section
|
||||
.apply(cosmic::Element::from)
|
||||
.map(crate::pages::Message::Power)
|
||||
})
|
||||
}
|
||||
|
||||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
|
@ -431,3 +431,16 @@ switch-to-next-workspace = Switch to next workspace
|
|||
switch-to-prev-workspace = Switch to prev workspace
|
||||
open-application-library = Open Application Library
|
||||
open-workspaces-view = Open Workspaces Overview
|
||||
|
||||
## Power
|
||||
|
||||
power = Power
|
||||
.desc = Manage power settings
|
||||
|
||||
power-profiles = Power Profiles
|
||||
.performance = Performance Mode
|
||||
.balanced = Balanced Mode
|
||||
.battery = Power Save Mode
|
||||
.performance-desc = Maximum performance but high power consumption.
|
||||
.balanced-desc = Balanced performance and power consumption.
|
||||
.battery-desc = Low performance but low power consumption.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue