diff --git a/Cargo.lock b/Cargo.lock index 3468317b..5c11250a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1242,8 +1242,13 @@ dependencies = [ name = "cosmic-panel-button" version = "0.1.0" dependencies = [ + "cosmic-config", "freedesktop-desktop-entry", "libcosmic", + "serde", + "tracing", + "tracing-log", + "tracing-subscriber", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7c8b6fb0..e520d3a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,8 @@ zbus = { version = "3.15", default-features = false, features = ["tokio"] } tracing = "0.1" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-log = "0.2.0" +cosmic-config = { git = "https://github.com/pop-os/libcosmic" } +serde = { version = "1.0.152", features = ["derive"] } [profile.release] lto = "fat" diff --git a/cosmic-panel-button/Cargo.toml b/cosmic-panel-button/Cargo.toml index 7690c2d0..4e1cb399 100644 --- a/cosmic-panel-button/Cargo.toml +++ b/cosmic-panel-button/Cargo.toml @@ -7,3 +7,8 @@ license = "GPL-3.0" [dependencies] freedesktop-desktop-entry = "0.5.1" libcosmic.workspace = true +tracing-log.workspace = true +tracing-subscriber.workspace = true +tracing.workspace = true +cosmic-config.workspace = true +serde.workspace = true \ No newline at end of file diff --git a/cosmic-panel-button/src/config.rs b/cosmic-panel-button/src/config.rs new file mode 100644 index 00000000..41727ab9 --- /dev/null +++ b/cosmic-panel-button/src/config.rs @@ -0,0 +1,44 @@ +use std::collections::HashMap; + +use cosmic_config::{cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, CosmicConfigEntry)] +#[version = 1] +#[serde(deny_unknown_fields)] +pub struct CosmicPanelButtonConfig { + /// configs indexed by panel name + pub configs: HashMap, +} + +impl Default for CosmicPanelButtonConfig { + fn default() -> Self { + Self { + configs: HashMap::from([ + ( + "Panel".to_string(), + IndividualConfig { + force_presentation: None, + }, + ), + ( + "Dock".to_string(), + IndividualConfig { + force_presentation: Some(Override::Icon), + }, + ), + ]), + } + } +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Default, Clone)] +pub struct IndividualConfig { + pub force_presentation: Option, +} + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub enum Override { + Icon, + Text, +} diff --git a/cosmic-panel-button/src/main.rs b/cosmic-panel-button/src/main.rs index 7ac9be19..bd6bfab6 100644 --- a/cosmic-panel-button/src/main.rs +++ b/cosmic-panel-button/src/main.rs @@ -1,15 +1,21 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +use config::{CosmicPanelButtonConfig, IndividualConfig, Override}; use cosmic::applet::cosmic_panel_config::PanelAnchor; use cosmic::iced::Length; use cosmic::iced_widget::{row, text}; use cosmic::widget::vertical_space; use cosmic::{app, iced, iced_style::application, theme::Theme}; +use cosmic_config::{Config, CosmicConfigEntry}; use freedesktop_desktop_entry::DesktopEntry; use std::{env, fs, process::Command}; -#[derive(Clone, Default)] +mod config; + +const VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[derive(Debug, Clone, Default)] struct Desktop { name: String, icon: Option, @@ -19,11 +25,13 @@ struct Desktop { struct Button { core: cosmic::app::Core, desktop: Desktop, + config: IndividualConfig, } #[derive(Debug, Clone)] enum Msg { Press, + ConfigUpdated(CosmicPanelButtonConfig), } impl cosmic::Application for Button { @@ -33,7 +41,22 @@ impl cosmic::Application for Button { const APP_ID: &'static str = "com.system76.CosmicPanelButton"; fn init(core: cosmic::app::Core, desktop: Desktop) -> (Self, app::Command) { - (Self { core, desktop }, app::Command::none()) + let config = Config::new(Self::APP_ID, CosmicPanelButtonConfig::VERSION) + .ok() + .and_then(|c| CosmicPanelButtonConfig::get_entry(&c).ok()) + .unwrap_or_default() + .configs + .get(&core.applet.panel_type.to_string()) + .cloned() + .unwrap_or_default(); + ( + Self { + core, + desktop, + config, + }, + app::Command::none(), + ) } fn core(&self) -> &cosmic::app::Core { @@ -53,15 +76,27 @@ impl cosmic::Application for Button { Msg::Press => { let _ = Command::new("sh").arg("-c").arg(&self.desktop.exec).spawn(); } + Msg::ConfigUpdated(conf) => { + self.config = conf + .configs + .get(&self.core.applet.panel_type.to_string()) + .cloned() + .unwrap_or_default(); + } } app::Command::none() } fn view(&self) -> cosmic::Element { - if matches!( - self.core.applet.anchor, - PanelAnchor::Left | PanelAnchor::Right - ) && self.desktop.icon.is_some() + // currently, panel being anchored to the left or right is a hard + // override for icon, later if text is updated to wrap, we may + // use Override::Text to override this behavior + if self.desktop.icon.is_some() + && matches!( + self.core.applet.anchor, + PanelAnchor::Left | PanelAnchor::Right + ) + || matches!(self.config.force_presentation, Some(Override::Icon)) { self.core .applet @@ -82,13 +117,25 @@ impl cosmic::Application for Button { .on_press(Msg::Press) .into() } + + fn subscription(&self) -> iced::Subscription { + self.core.watch_config(Self::APP_ID).map(|u| { + for why in u.errors { + tracing::error!(why = why.to_string(), "Error watching config"); + } + Msg::ConfigUpdated(u.config) + }) + } } pub fn main() -> iced::Result { + tracing_subscriber::fmt::init(); + let _ = tracing_log::LogTracer::init(); + tracing::info!("Starting panel button applet with version {VERSION}"); + let id = env::args() .nth(1) .expect("Requires desktop file id as argument."); - let filename = format!("{id}.desktop"); let mut desktop = None; for mut path in freedesktop_desktop_entry::default_paths() {