From 5d4ef7736761d61ce0a1ca284b333276e342b6c4 Mon Sep 17 00:00:00 2001 From: Ryan Brue Date: Mon, 6 May 2024 16:58:25 -0500 Subject: [PATCH] feat(panel-button): add applet config This PR adds an optional environment variable to the cosmic-panel-button that allows us to specify how a panel button should present itself (either as 'icon' or as 'text'). The PR also adds the same tracing log that the other applets have, with an initial message notifying that the applet has started. --- Cargo.lock | 5 +++ Cargo.toml | 2 + cosmic-panel-button/Cargo.toml | 5 +++ cosmic-panel-button/src/config.rs | 44 ++++++++++++++++++++++ cosmic-panel-button/src/main.rs | 61 +++++++++++++++++++++++++++---- 5 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 cosmic-panel-button/src/config.rs 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() {