perf(desktop): reduce disk usage when reading and writing configs

This commit is contained in:
Michael Aaron Murphy 2024-09-18 13:49:17 +02:00 committed by Michael Murphy
parent 395b922984
commit 94562eae88
5 changed files with 649 additions and 401 deletions

View file

@ -100,6 +100,7 @@ pub enum Message {
DelayedInit(page::Entity), DelayedInit(page::Entity),
DesktopInfo, DesktopInfo,
Error(String), Error(String),
None,
OpenContextDrawer(Cow<'static, str>), OpenContextDrawer(Cow<'static, str>),
OutputAdded(OutputInfo, WlOutput), OutputAdded(OutputInfo, WlOutput),
OutputRemoved(WlOutput), OutputRemoved(WlOutput),
@ -290,6 +291,8 @@ impl cosmic::Application for SettingsApp {
match message { match message {
Message::Page(page) => return self.activate_page(page), Message::Page(page) => return self.activate_page(page),
Message::None => (),
Message::SetWindowTitle => return self.set_title(), Message::SetWindowTitle => return self.set_title(),
Message::SearchChanged(phrase) => { Message::SearchChanged(phrase) => {
@ -347,7 +350,9 @@ impl cosmic::Application for SettingsApp {
} }
crate::pages::Message::Dock(message) => { crate::pages::Message::Dock(message) => {
page::update!(self.pages, message, dock::Page); if let Some(page) = self.pages.page_mut::<dock::Page>() {
return page.update(message).map(Into::into);
}
} }
crate::pages::Message::DockApplet(message) => { crate::pages::Message::DockApplet(message) => {
@ -443,7 +448,9 @@ impl cosmic::Application for SettingsApp {
} }
crate::pages::Message::Panel(message) => { crate::pages::Message::Panel(message) => {
page::update!(self.pages, message, panel::Page); if let Some(page) = self.pages.page_mut::<panel::Page>() {
return page.update(message).map(Into::into);
}
} }
crate::pages::Message::PanelApplet(message) => { crate::pages::Message::PanelApplet(message) => {
@ -481,57 +488,82 @@ impl cosmic::Application for SettingsApp {
Message::OutputAdded(info, output) => { Message::OutputAdded(info, output) => {
if let Some(page) = self.pages.page_mut::<panel::Page>() { if let Some(page) = self.pages.page_mut::<panel::Page>() {
page.update(panel::Message(_panel::Message::OutputAdded( return page
info.name.clone().unwrap_or_default(), .update(panel::Message(_panel::Message::OutputAdded(
output.clone(), info.name.clone().unwrap_or_default(),
))); output.clone(),
)))
.map(Into::into);
} }
// dock
if let Some(page) = self.pages.page_mut::<dock::Page>() { if let Some(page) = self.pages.page_mut::<dock::Page>() {
page.update(dock::Message::Inner(_panel::Message::OutputAdded( return page
info.name.unwrap_or_default(), .update(dock::Message::Inner(_panel::Message::OutputAdded(
output, info.name.unwrap_or_default(),
))); output,
)))
.map(Into::into);
} }
} }
Message::OutputRemoved(output) => { Message::OutputRemoved(output) => {
if let Some(page) = self.pages.page_mut::<panel::Page>() { if let Some(page) = self.pages.page_mut::<panel::Page>() {
page.update(panel::Message(_panel::Message::OutputRemoved(
output.clone(),
)));
}
// dock
if let Some(page) = self.pages.page_mut::<dock::Page>() {
page.update(dock::Message::Inner(_panel::Message::OutputRemoved(output)));
}
}
Message::PanelConfig(config) if config.name.to_lowercase().contains("panel") => {
page::update!(
self.pages,
panel::Message(_panel::Message::PanelConfig(config.clone())),
panel::Page
);
if let Some(page) = self.pages.page_mut::<applets_inner::Page>() {
return page return page
.update(applets_inner::Message::PanelConfig(config)) .update(panel::Message(_panel::Message::OutputRemoved(
output.clone(),
)))
.map(Into::into);
}
if let Some(page) = self.pages.page_mut::<dock::Page>() {
return page
.update(dock::Message::Inner(_panel::Message::OutputRemoved(output)))
.map(Into::into); .map(Into::into);
} }
} }
Message::PanelConfig(config) if config.name.to_lowercase().contains("panel") => {
let mut commands = Vec::new();
if let Some(page) = self.pages.page_mut::<panel::Page>() {
commands.push(
page.update(panel::Message(_panel::Message::PanelConfig(config.clone())))
.map(Into::into),
);
}
if let Some(page) = self.pages.page_mut::<applets_inner::Page>() {
commands.push(
page.update(applets_inner::Message::PanelConfig(config))
.map(Into::into),
);
}
return Command::batch(commands);
}
Message::PanelConfig(config) if config.name.to_lowercase().contains("dock") => { Message::PanelConfig(config) if config.name.to_lowercase().contains("dock") => {
page::update!( let mut commands = Vec::new();
self.pages,
dock::Message::Inner(_panel::Message::PanelConfig(config.clone(),)), if let Some(page) = self.pages.page_mut::<dock::Page>() {
dock::Page commands.push(
); page.update(dock::Message::Inner(_panel::Message::PanelConfig(
page::update!( config.clone(),
self.pages, )))
dock::applets::Message(applets_inner::Message::PanelConfig(config,)), .map(Into::into),
dock::applets::Page );
); }
if let Some(page) = self.pages.page_mut::<dock::applets::Page>() {
commands.push(
page.update(dock::applets::Message(applets_inner::Message::PanelConfig(
config,
)))
.map(Into::into),
);
}
return Command::batch(commands);
} }
Message::PanelConfig(_) => {} Message::PanelConfig(_) => {}

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@ use cosmic::Apply;
use cosmic::{ use cosmic::{
cosmic_config::{ConfigSet, CosmicConfigEntry}, cosmic_config::{ConfigSet, CosmicConfigEntry},
widget::{settings, text, toggler}, widget::{settings, text, toggler},
Element, Command, Element,
}; };
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig}; use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -31,17 +31,19 @@ pub enum Message {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) { pub fn update(&mut self, message: Message) -> Command<crate::app::Message> {
match message { match message {
Message::EnableDock(enabled) => { Message::EnableDock(enabled) => {
let Some(container_config) = self.inner.container_config.as_mut() else { let Some(container_config) = self.inner.container_config.as_mut() else {
return; return Command::none();
}; };
let Some(panel_config) = self.inner.panel_config.as_ref() else { let Some(panel_config) = self.inner.panel_config.as_ref() else {
return; return Command::none();
}; };
let Ok(helper) = CosmicPanelContainerConfig::cosmic_config() else { let Ok(helper) = CosmicPanelContainerConfig::cosmic_config() else {
return; return Command::none();
}; };
if enabled { if enabled {
@ -61,11 +63,16 @@ impl Page {
if let Err(err) = helper.set("entries", entry_names) { if let Err(err) = helper.set("entries", entry_names) {
error!("{:?}", err); error!("{:?}", err);
} }
Command::none()
} }
Message::Inner(inner) => { Message::Inner(inner) => self
self.inner.update(inner); .inner
} .update(inner)
}; .map(Message::Inner)
.map(crate::pages::Message::Dock)
.map(crate::app::Message::PageMessage),
}
} }
} }
@ -109,11 +116,13 @@ impl Default for Page {
fn default() -> Self { fn default() -> Self {
// TODO CosmicPanelConfig should return its own version // TODO CosmicPanelConfig should return its own version
let config_helper = CosmicPanelConfig::cosmic_config("Dock").ok(); let config_helper = CosmicPanelConfig::cosmic_config("Dock").ok();
let panel_config = config_helper.as_ref().and_then(|config_helper| { let panel_config = config_helper.as_ref().and_then(|config_helper| {
let panel_config = CosmicPanelConfig::get_entry(config_helper).ok()?; let panel_config = CosmicPanelConfig::get_entry(config_helper).ok()?;
// If the config is not present, it will be created with the default values and the name will not match // If the config is not present, it will be created with the default values and the name will not match
(panel_config.name == "Dock").then_some(panel_config) (panel_config.name == "Dock").then_some(panel_config)
}); });
let system_default = cosmic::cosmic_config::Config::system( let system_default = cosmic::cosmic_config::Config::system(
&format!("{}.Dock", cosmic_panel_config::NAME), &format!("{}.Dock", cosmic_panel_config::NAME),
CosmicPanelConfig::VERSION, CosmicPanelConfig::VERSION,
@ -128,6 +137,7 @@ impl Default for Page {
} }
}) })
.ok(); .ok();
let container_config = CosmicPanelContainerConfig::load().ok(); let container_config = CosmicPanelContainerConfig::load().ok();
Self { Self {
inner: PageInner { inner: PageInner {

View file

@ -6,21 +6,24 @@ use cosmic::{
widget::{ widget::{
button, container, dropdown, horizontal_space, icon, row, settings, slider, text, toggler, button, container, dropdown, horizontal_space, icon, row, settings, slider, text, toggler,
}, },
Element, Command, Element,
}; };
use cosmic::Apply; use cosmic::Apply;
use cosmic_config::ConfigSet;
use cosmic_panel_config::{ use cosmic_panel_config::{
AutoHide, CosmicPanelBackground, CosmicPanelConfig, CosmicPanelContainerConfig, AutoHide, CosmicPanelBackground, CosmicPanelConfig, CosmicPanelContainerConfig,
CosmicPanelOuput, PanelAnchor, PanelSize, CosmicPanelOuput, PanelAnchor, PanelSize,
}; };
use cosmic_settings_page::{self as page, Section}; use cosmic_settings_page::{self as page, Section};
use slab::Slab; use slab::Slab;
use std::collections::HashMap; use std::{collections::HashMap, time::Duration};
pub struct PageInner { pub struct PageInner {
pub(crate) config_helper: Option<cosmic_config::Config>, pub(crate) config_helper: Option<cosmic_config::Config>,
pub(crate) panel_config: Option<CosmicPanelConfig>, pub(crate) panel_config: Option<CosmicPanelConfig>,
pub opacity: f32,
pub opacity_changing: bool,
pub outputs: Vec<String>, pub outputs: Vec<String>,
pub anchors: Vec<String>, pub anchors: Vec<String>,
pub backgrounds: Vec<String>, pub backgrounds: Vec<String>,
@ -36,6 +39,8 @@ impl Default for PageInner {
Self { Self {
config_helper: Option::default(), config_helper: Option::default(),
panel_config: Option::default(), panel_config: Option::default(),
opacity: 0.0,
opacity_changing: false,
outputs: vec![fl!("all-displays")], outputs: vec![fl!("all-displays")],
anchors: vec![ anchors: vec![
Anchor(PanelAnchor::Left).to_string(), Anchor(PanelAnchor::Left).to_string(),
@ -226,16 +231,22 @@ pub(crate) fn style<
)) ))
.add(settings::flex_item( .add(settings::flex_item(
&descriptions[background_opacity], &descriptions[background_opacity],
row::with_children(vec![ row::with_capacity(3)
text::body(fl!("number", HashMap::from_iter(vec![("number", 0)]))).into(), .push(text::body(fl!(
slider(0..=100, (panel_config.opacity * 100.0) as i32, |v| { "number",
Message::Opacity(v as f32 / 100.0) HashMap::from_iter(vec![("number", 0)])
}) )))
.breakpoints(&[50]) .push(
.into(), slider(0..=100, (panel_config.opacity * 100.0) as i32, |v| {
text::body(fl!("number", HashMap::from_iter(vec![("number", 100)]))).into(), Message::OpacityRequest(v as f32 / 100.0)
]) })
.spacing(12), .breakpoints(&[50]),
)
.push(text::body(fl!(
"number",
HashMap::from_iter(vec![("number", 100)])
)))
.spacing(12),
)) ))
.apply(Element::from) .apply(Element::from)
.map(msg_map) .map(msg_map)
@ -396,7 +407,8 @@ pub enum Message {
PanelSize(PanelSize), PanelSize(PanelSize),
Appearance(usize), Appearance(usize),
ExtendToEdge(bool), ExtendToEdge(bool),
Opacity(f32), OpacityRequest(f32),
OpacityApply,
OutputAdded(String, WlOutput), OutputAdded(String, WlOutput),
OutputRemoved(WlOutput), OutputRemoved(WlOutput),
PanelConfig(CosmicPanelConfig), PanelConfig(CosmicPanelConfig),
@ -406,10 +418,11 @@ pub enum Message {
impl PageInner { impl PageInner {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) { pub fn update(&mut self, message: Message) -> Command<Message> {
let Some(helper) = self.config_helper.as_ref() else { let Some(helper) = self.config_helper.as_ref() else {
return; return Command::none();
}; };
match &message { match &message {
Message::ResetPanel => { Message::ResetPanel => {
if let Some((default, config)) = self if let Some((default, config)) = self
@ -445,7 +458,7 @@ impl PageInner {
}; };
let Some(panel_config) = self.panel_config.as_mut() else { let Some(panel_config) = self.panel_config.as_mut() else {
return; return Command::none();
}; };
match message { match message {
@ -509,13 +522,29 @@ impl PageInner {
Message::ExtendToEdge(enabled) => { Message::ExtendToEdge(enabled) => {
_ = panel_config.set_expand_to_edges(helper, enabled); _ = panel_config.set_expand_to_edges(helper, enabled);
} }
Message::Opacity(opacity) => { Message::OpacityRequest(opacity) => {
_ = panel_config.set_opacity(helper, opacity); panel_config.opacity = opacity;
if self.opacity_changing {
return Command::none();
}
self.opacity_changing = true;
return cosmic::command::future(async move {
tokio::time::sleep(Duration::from_millis(125)).await;
Message::OpacityApply
});
} }
Message::OpacityApply => {
self.opacity_changing = false;
_ = helper.set("opacity", panel_config.opacity);
}
Message::OutputAdded(name, output) => { Message::OutputAdded(name, output) => {
self.outputs.push(name.clone()); self.outputs.push(name.clone());
self.outputs_map.insert(output.id(), (name, output)); self.outputs_map.insert(output.id(), (name, output));
return; return Command::none();
} }
Message::OutputRemoved(output) => { Message::OutputRemoved(output) => {
if let Some((name, _)) = self.outputs_map.remove(&output.id()) { if let Some((name, _)) = self.outputs_map.remove(&output.id()) {
@ -526,7 +555,7 @@ impl PageInner {
} }
Message::PanelConfig(c) => { Message::PanelConfig(c) => {
self.panel_config = Some(c); self.panel_config = Some(c);
return; return Command::none();
} }
Message::ResetPanel | Message::FullReset => {} Message::ResetPanel | Message::FullReset => {}
} }
@ -540,5 +569,7 @@ impl PageInner {
} else { } else {
_ = panel_config.set_border_radius(helper, 0); _ = panel_config.set_border_radius(helper, 0);
} }
Command::none()
} }
} }

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use cosmic::cosmic_config::CosmicConfigEntry; use cosmic::{cosmic_config::CosmicConfigEntry, Command};
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig}; use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use slotmap::SlotMap; use slotmap::SlotMap;
@ -22,8 +22,12 @@ pub struct Page {
pub struct Message(pub inner::Message); pub struct Message(pub inner::Message);
impl Page { impl Page {
pub fn update(&mut self, message: Message) { pub fn update(&mut self, message: Message) -> Command<crate::app::Message> {
self.inner.update(message.0); self.inner
.update(message.0)
.map(Message)
.map(crate::pages::Message::Panel)
.map(crate::app::Message::PageMessage)
} }
} }