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.
This commit is contained in:
Ryan Brue 2024-05-06 16:58:25 -05:00 committed by Ashley Wulber
parent 40509c669f
commit 5d4ef77367
5 changed files with 110 additions and 7 deletions

5
Cargo.lock generated
View file

@ -1242,8 +1242,13 @@ dependencies = [
name = "cosmic-panel-button" name = "cosmic-panel-button"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cosmic-config",
"freedesktop-desktop-entry", "freedesktop-desktop-entry",
"libcosmic", "libcosmic",
"serde",
"tracing",
"tracing-log",
"tracing-subscriber",
] ]
[[package]] [[package]]

View file

@ -52,6 +52,8 @@ zbus = { version = "3.15", default-features = false, features = ["tokio"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing-log = "0.2.0" tracing-log = "0.2.0"
cosmic-config = { git = "https://github.com/pop-os/libcosmic" }
serde = { version = "1.0.152", features = ["derive"] }
[profile.release] [profile.release]
lto = "fat" lto = "fat"

View file

@ -7,3 +7,8 @@ license = "GPL-3.0"
[dependencies] [dependencies]
freedesktop-desktop-entry = "0.5.1" freedesktop-desktop-entry = "0.5.1"
libcosmic.workspace = true libcosmic.workspace = true
tracing-log.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true
cosmic-config.workspace = true
serde.workspace = true

View file

@ -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<String, IndividualConfig>,
}
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<Override>,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum Override {
Icon,
Text,
}

View file

@ -1,15 +1,21 @@
// Copyright 2023 System76 <info@system76.com> // Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use config::{CosmicPanelButtonConfig, IndividualConfig, Override};
use cosmic::applet::cosmic_panel_config::PanelAnchor; use cosmic::applet::cosmic_panel_config::PanelAnchor;
use cosmic::iced::Length; use cosmic::iced::Length;
use cosmic::iced_widget::{row, text}; use cosmic::iced_widget::{row, text};
use cosmic::widget::vertical_space; use cosmic::widget::vertical_space;
use cosmic::{app, iced, iced_style::application, theme::Theme}; use cosmic::{app, iced, iced_style::application, theme::Theme};
use cosmic_config::{Config, CosmicConfigEntry};
use freedesktop_desktop_entry::DesktopEntry; use freedesktop_desktop_entry::DesktopEntry;
use std::{env, fs, process::Command}; use std::{env, fs, process::Command};
#[derive(Clone, Default)] mod config;
const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Debug, Clone, Default)]
struct Desktop { struct Desktop {
name: String, name: String,
icon: Option<String>, icon: Option<String>,
@ -19,11 +25,13 @@ struct Desktop {
struct Button { struct Button {
core: cosmic::app::Core, core: cosmic::app::Core,
desktop: Desktop, desktop: Desktop,
config: IndividualConfig,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Msg { enum Msg {
Press, Press,
ConfigUpdated(CosmicPanelButtonConfig),
} }
impl cosmic::Application for Button { impl cosmic::Application for Button {
@ -33,7 +41,22 @@ impl cosmic::Application for Button {
const APP_ID: &'static str = "com.system76.CosmicPanelButton"; const APP_ID: &'static str = "com.system76.CosmicPanelButton";
fn init(core: cosmic::app::Core, desktop: Desktop) -> (Self, app::Command<Msg>) { fn init(core: cosmic::app::Core, desktop: Desktop) -> (Self, app::Command<Msg>) {
(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 { fn core(&self) -> &cosmic::app::Core {
@ -53,15 +76,27 @@ impl cosmic::Application for Button {
Msg::Press => { Msg::Press => {
let _ = Command::new("sh").arg("-c").arg(&self.desktop.exec).spawn(); 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() app::Command::none()
} }
fn view(&self) -> cosmic::Element<Msg> { fn view(&self) -> cosmic::Element<Msg> {
if matches!( // currently, panel being anchored to the left or right is a hard
self.core.applet.anchor, // override for icon, later if text is updated to wrap, we may
PanelAnchor::Left | PanelAnchor::Right // use Override::Text to override this behavior
) && self.desktop.icon.is_some() 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 self.core
.applet .applet
@ -82,13 +117,25 @@ impl cosmic::Application for Button {
.on_press(Msg::Press) .on_press(Msg::Press)
.into() .into()
} }
fn subscription(&self) -> iced::Subscription<Self::Message> {
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 { 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() let id = env::args()
.nth(1) .nth(1)
.expect("Requires desktop file id as argument."); .expect("Requires desktop file id as argument.");
let filename = format!("{id}.desktop"); let filename = format!("{id}.desktop");
let mut desktop = None; let mut desktop = None;
for mut path in freedesktop_desktop_entry::default_paths() { for mut path in freedesktop_desktop_entry::default_paths() {