feat: theme management

This commit is contained in:
Ashley Wulber 2023-06-09 16:10:20 -04:00 committed by Ashley Wulber
parent 3ec06bef80
commit 76bf6a4519
14 changed files with 213 additions and 42 deletions

1
Cargo.lock generated
View file

@ -695,6 +695,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"cosmic-panel-config", "cosmic-panel-config",
"libcosmic", "libcosmic",
"log",
"ron", "ron",
"serde", "serde",
] ]

View file

@ -10,3 +10,4 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "5765053", def
ron = { version = "0.8" } ron = { version = "0.8" }
serde = { version = "1.0" } serde = { version = "1.0" }
cosmic-panel-config = { git = "https://github.com/pop-os/cosmic-panel", rev = "6cef482" } cosmic-panel-config = { git = "https://github.com/pop-os/cosmic-panel", rev = "6cef482" }
log = { version = "0.4" }

View file

@ -1,10 +1,15 @@
use std::sync::Arc;
use cosmic::{ use cosmic::{
cosmic_config::{config_subscription, CosmicConfigEntry},
cosmic_theme::util::CssColor,
iced::{ iced::{
alignment::{Horizontal, Vertical}, alignment::{Horizontal, Vertical},
wayland::InitialSurface, wayland::InitialSurface,
widget::{self, Container}, widget::{self, Container},
window, Limits, Color, Element, Length, Rectangle, Settings, window, Color, Element, Length, Limits, Rectangle, Settings,
}, },
iced_futures::Subscription,
iced_style, iced_widget, sctk, iced_style, iced_widget, sctk,
theme::Button, theme::Button,
Renderer, Renderer,
@ -15,6 +20,7 @@ use iced_widget::runtime::command::platform_specific::wayland::{
popup::{SctkPopupSettings, SctkPositioner}, popup::{SctkPopupSettings, SctkPositioner},
window::SctkWindowSettings, window::SctkWindowSettings,
}; };
use log::error;
use sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{Anchor, Gravity}; use sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{Anchor, Gravity};
pub use cosmic_panel_config; pub use cosmic_panel_config;
@ -199,4 +205,52 @@ impl CosmicAppletHelper {
grab: true, grab: true,
} }
} }
pub fn theme(&self) -> cosmic::theme::Theme {
match self.background {
CosmicPanelBackground::ThemeDefault | CosmicPanelBackground::Color(_) => {
let Ok(helper) = cosmic::cosmic_config::Config::new(
cosmic::cosmic_theme::NAME,
cosmic::cosmic_theme::Theme::<CssColor>::version() as u64,
) else {
return cosmic::theme::Theme::dark();
};
let t = cosmic::cosmic_theme::Theme::get_entry(&helper)
.map(|t| t.into_srgba())
.unwrap_or_else(|(errors, theme)| {
for err in errors {
error!("{:?}", err);
}
theme.into_srgba()
});
cosmic::theme::Theme::custom(Arc::new(t))
}
CosmicPanelBackground::Dark => cosmic::theme::Theme::dark(),
CosmicPanelBackground::Light => cosmic::theme::Theme::light(),
}
}
pub fn theme_subscription(&self, id: u64) -> Subscription<cosmic::theme::Theme> {
match self.background {
CosmicPanelBackground::ThemeDefault | CosmicPanelBackground::Color(_) => {
config_subscription::<u64, cosmic::cosmic_theme::Theme<CssColor>>(
id,
cosmic::cosmic_theme::NAME.into(),
cosmic::cosmic_theme::Theme::<CssColor>::version() as u64,
)
.map(|(_, res)| {
let theme =
res.map(|theme| theme.into_srgba())
.unwrap_or_else(|(errors, theme)| {
for err in errors {
error!("{:?}", err);
}
theme.into_srgba()
});
cosmic::theme::Theme::custom(Arc::new(theme))
})
}
CosmicPanelBackground::Dark | CosmicPanelBackground::Light => Subscription::none(),
}
}
} }

View file

@ -267,6 +267,7 @@ enum Message {
StopListeningForDnd, StopListeningForDnd,
IncrementSubscriptionCtr, IncrementSubscriptionCtr,
ConfigUpdated(AppListConfig), ConfigUpdated(AppListConfig),
Theme(Theme),
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -368,6 +369,8 @@ impl Application for CosmicAppList {
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let config = config::AppListConfig::load().unwrap_or_default(); let config = config::AppListConfig::load().unwrap_or_default();
let helper = CosmicAppletHelper::default();
let theme = helper.theme();
let mut self_ = CosmicAppList { let mut self_ = CosmicAppList {
favorite_list: desktop_info_for_app_ids(config.favorites.clone()) favorite_list: desktop_info_for_app_ids(config.favorites.clone())
.into_iter() .into_iter()
@ -378,7 +381,9 @@ impl Application for CosmicAppList {
desktop_info: e, desktop_info: e,
}) })
.collect(), .collect(),
applet_helper: helper,
config, config,
theme,
..Default::default() ..Default::default()
}; };
self_.item_ctr = self_.favorite_list.len() as u32; self_.item_ctr = self_.favorite_list.len() as u32;
@ -835,6 +840,9 @@ impl Application for CosmicAppList {
self.favorite_list = new_list; self.favorite_list = new_list;
} }
Message::Theme(t) => {
self.theme = t;
}
} }
Command::none() Command::none()
} }
@ -1051,6 +1059,7 @@ impl Application for CosmicAppList {
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![ Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
toplevel_subscription(self.subscription_ctr).map(|e| Message::Toplevel(e.1)), toplevel_subscription(self.subscription_ctr).map(|e| Message::Toplevel(e.1)),
events_with(|e, _| match e { events_with(|e, _| match e {
cosmic::iced_runtime::core::Event::PlatformSpecific( cosmic::iced_runtime::core::Event::PlatformSpecific(

View file

@ -16,10 +16,7 @@ use cosmic::iced::{
}; };
use cosmic::iced_style::application::{self, Appearance}; use cosmic::iced_style::application::{self, Appearance};
use cosmic::{Element, Theme}; use cosmic::{Element, Theme};
use cosmic_time::{ use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
once_cell::sync::Lazy,
anim, chain, id, Timeline, Instant,
};
use iced::wayland::popup::{destroy_popup, get_popup}; use iced::wayland::popup::{destroy_popup, get_popup};
use iced::widget::container; use iced::widget::container;
@ -79,6 +76,7 @@ enum Message {
TogglePopup, TogglePopup,
ToggleMediaControlsInTopPanel(chain::Toggler, bool), ToggleMediaControlsInTopPanel(chain::Toggler, bool),
Frame(Instant), Frame(Instant),
Theme(Theme),
} }
impl Application for Audio { impl Application for Audio {
@ -88,6 +86,8 @@ impl Application for Audio {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Audio, Command<Message>) { fn new(_flags: ()) -> (Audio, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
Audio { Audio {
is_open: IsOpen::None, is_open: IsOpen::None,
@ -96,6 +96,8 @@ impl Application for Audio {
outputs: vec![], outputs: vec![],
inputs: vec![], inputs: vec![],
icon_name: "audio-volume-high-symbolic".to_string(), icon_name: "audio-volume-high-symbolic".to_string(),
applet_helper,
theme,
..Default::default() ..Default::default()
}, },
Command::none(), Command::none(),
@ -123,9 +125,7 @@ impl Application for Audio {
fn update(&mut self, message: Message) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::Frame(now) => { Message::Frame(now) => self.timeline.now(now),
self.timeline.now(now)
},
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return destroy_popup(p);
@ -276,14 +276,19 @@ impl Application for Audio {
self.timeline.set_chain(chain).start(); self.timeline.set_chain(chain).start();
self.show_media_controls_in_top_panel = enabled; self.show_media_controls_in_top_panel = enabled;
} }
Message::Theme(t) => {
self.theme = t;
}
}; };
Command::none() Command::none()
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![pulse::connect().map(Message::Pulse), Subscription::batch(vec![
self.timeline.as_subscription().map(Message::Frame), self.applet_helper.theme_subscription(0).map(Message::Theme),
pulse::connect().map(Message::Pulse),
self.timeline.as_subscription().map(Message::Frame),
]) ])
} }
@ -389,13 +394,15 @@ impl Application for Audio {
.padding([12, 24]) .padding([12, 24])
.width(Length::Fill), .width(Length::Fill),
container( container(
anim!( // toggler anim!(
SHOW_MEDIA_CONTROLS, // toggler
&self.timeline, SHOW_MEDIA_CONTROLS,
Some(fl!("show-media-controls")), &self.timeline,
self.show_media_controls_in_top_panel, Some(fl!("show-media-controls")),
Message::ToggleMediaControlsInTopPanel, self.show_media_controls_in_top_panel,
).text_size(14) Message::ToggleMediaControlsInTopPanel,
)
.text_size(14)
) )
.padding([0, 24]), .padding([0, 24]),
container(divider::horizontal::light()) container(divider::horizontal::light())

View file

@ -23,10 +23,7 @@ use cosmic::theme::Svg;
use cosmic::widget::{button, divider, icon}; use cosmic::widget::{button, divider, icon};
use cosmic::{Element, Theme}; use cosmic::{Element, Theme};
use cosmic_applet::{applet_button_theme, CosmicAppletHelper}; use cosmic_applet::{applet_button_theme, CosmicAppletHelper};
use cosmic_time::{ use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
once_cell::sync::Lazy,
anim, chain, id, Timeline, Instant,
};
use log::error; use log::error;
use std::time::Duration; use std::time::Duration;
@ -96,6 +93,7 @@ enum Message {
Profile(Power), Profile(Power),
SelectProfile(Power), SelectProfile(Power),
Frame(Instant), Frame(Instant),
Theme(Theme),
} }
impl Application for CosmicBatteryApplet { impl Application for CosmicBatteryApplet {
@ -105,9 +103,13 @@ impl Application for CosmicBatteryApplet {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
CosmicBatteryApplet { CosmicBatteryApplet {
icon_name: "battery-symbolic".to_string(), icon_name: "battery-symbolic".to_string(),
applet_helper,
theme,
..Default::default() ..Default::default()
}, },
Command::none(), Command::none(),
@ -220,6 +222,9 @@ impl Application for CosmicBatteryApplet {
let _ = tx.send(PowerProfileRequest::Set(profile)); let _ = tx.send(PowerProfileRequest::Set(profile));
} }
} }
Message::Theme(t) => {
self.theme = t;
}
} }
Command::none() Command::none()
} }
@ -320,7 +325,8 @@ impl Application for CosmicBatteryApplet {
.width(Length::Fill) .width(Length::Fill)
.padding([0, 12]), .padding([0, 12]),
container( container(
anim!( //toggler anim!(
//toggler
MAX_CHARGE, MAX_CHARGE,
&self.timeline, &self.timeline,
fl!("max-charge"), fl!("max-charge"),
@ -384,6 +390,7 @@ impl Application for CosmicBatteryApplet {
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![ Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
device_subscription(0).map( device_subscription(0).map(
|( |(
_, _,

View file

@ -53,6 +53,7 @@ enum Message {
Request(BluerRequest), Request(BluerRequest),
Cancel, Cancel,
Confirm, Confirm,
Theme(Theme),
} }
impl Application for CosmicBluetoothApplet { impl Application for CosmicBluetoothApplet {
@ -62,9 +63,13 @@ impl Application for CosmicBluetoothApplet {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
CosmicBluetoothApplet { CosmicBluetoothApplet {
icon_name: "bluetooth-symbolic".to_string(), icon_name: "bluetooth-symbolic".to_string(),
theme,
applet_helper,
..Default::default() ..Default::default()
}, },
Command::none(), Command::none(),
@ -267,6 +272,9 @@ impl Application for CosmicBluetoothApplet {
); );
} }
} }
Message::Theme(t) => {
self.theme = t;
}
} }
Command::none() Command::none()
} }
@ -513,7 +521,10 @@ impl Application for CosmicBluetoothApplet {
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
bluetooth_subscription(0).map(|(_, e)| Message::BluetoothEvent(e)) Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
bluetooth_subscription(0).map(|(_, e)| Message::BluetoothEvent(e)),
])
} }
fn theme(&self) -> Theme { fn theme(&self) -> Theme {

View file

@ -3,6 +3,7 @@ use crate::fl;
use crate::graphics::{get_current_graphics, set_graphics, Graphics}; use crate::graphics::{get_current_graphics, set_graphics, Graphics};
use cosmic::iced::wayland::popup::{destroy_popup, get_popup}; use cosmic::iced::wayland::popup::{destroy_popup, get_popup};
use cosmic::iced::Color; use cosmic::iced::Color;
use cosmic::iced_futures::Subscription;
use cosmic::iced_runtime::core::alignment::Horizontal; use cosmic::iced_runtime::core::alignment::Horizontal;
use cosmic::iced_runtime::core::Alignment; use cosmic::iced_runtime::core::Alignment;
use cosmic::iced_style::application::{self, Appearance}; use cosmic::iced_style::application::{self, Appearance};
@ -55,6 +56,7 @@ pub enum Message {
SelectGraphicsMode(Graphics), SelectGraphicsMode(Graphics),
TogglePopup, TogglePopup,
PopupClosed(window::Id), PopupClosed(window::Id),
Theme(Theme),
} }
impl Application for Window { impl Application for Window {
@ -64,7 +66,13 @@ impl Application for Window {
type Theme = Theme; type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<Self::Message>) { fn new(_flags: ()) -> (Self, Command<Self::Message>) {
let window = Window::default(); let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
let window = Window {
theme,
applet_helper,
..Default::default()
};
(window, Command::perform(dbus::init(), Message::DBusInit)) (window, Command::perform(dbus::init(), Message::DBusInit))
} }
@ -74,6 +82,9 @@ impl Application for Window {
fn update(&mut self, message: Message) -> iced::Command<Self::Message> { fn update(&mut self, message: Message) -> iced::Command<Self::Message> {
match message { match message {
Message::Theme(t) => {
self.theme = t;
}
Message::SelectGraphicsMode(new) => { Message::SelectGraphicsMode(new) => {
if let Some((_, proxy)) = self.dbus.as_ref() { if let Some((_, proxy)) = self.dbus.as_ref() {
let prev = self let prev = self
@ -383,6 +394,9 @@ impl Application for Window {
.into() .into()
} }
} }
fn subscription(&self) -> Subscription<Message> {
self.applet_helper.theme_subscription(0).map(Message::Theme)
}
fn close_requested(&self, id: window::Id) -> Self::Message { fn close_requested(&self, id: window::Id) -> Self::Message {
if id != window::Id(0) { if id != window::Id(0) {

View file

@ -158,6 +158,7 @@ pub(crate) enum Message {
Password(String), Password(String),
SubmitPassword, SubmitPassword,
Frame(Instant), Frame(Instant),
Theme(Theme),
// Errored(String), // Errored(String),
} }
@ -168,9 +169,13 @@ impl Application for CosmicNetworkApplet {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
CosmicNetworkApplet { CosmicNetworkApplet {
icon_name: "network-offline-symbolic".to_string(), icon_name: "network-offline-symbolic".to_string(),
theme,
applet_helper,
..Default::default() ..Default::default()
}, },
Command::none(), Command::none(),
@ -183,6 +188,9 @@ impl Application for CosmicNetworkApplet {
fn update(&mut self, message: Message) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::Theme(t) => {
self.theme = t;
}
Message::Frame(now) => self.timeline.now(now), Message::Frame(now) => self.timeline.now(now),
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
@ -725,6 +733,7 @@ impl Application for CosmicNetworkApplet {
if let Some(conn) = self.conn.as_ref() { if let Some(conn) = self.conn.as_ref() {
Subscription::batch(vec![ Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
timeline, timeline,
network_sub, network_sub,
active_conns_subscription(0, conn.clone()) active_conns_subscription(0, conn.clone())

View file

@ -42,6 +42,7 @@ enum Message {
Settings, Settings,
Ignore, Ignore,
Frame(Instant), Frame(Instant),
Theme(Theme),
} }
impl Application for Notifications { impl Application for Notifications {
@ -51,8 +52,12 @@ impl Application for Notifications {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Notifications, Command<Message>) { fn new(_flags: ()) -> (Notifications, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
Notifications { Notifications {
applet_helper,
theme,
icon_name: "notification-alert-symbolic".to_string(), icon_name: "notification-alert-symbolic".to_string(),
..Default::default() ..Default::default()
}, },
@ -80,11 +85,18 @@ impl Application for Notifications {
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
self.timeline.as_subscription().map(Message::Frame) Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
self.timeline.as_subscription().map(Message::Frame),
])
} }
fn update(&mut self, message: Message) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::Theme(t) => {
self.theme = t;
Command::none()
}
Message::Frame(now) => { Message::Frame(now) => {
self.timeline.now(now); self.timeline.now(now);
Command::none() Command::none()

View file

@ -74,6 +74,7 @@ enum Message {
Cancel, Cancel,
Closed(window::Id), Closed(window::Id),
Zbus(Result<(), zbus::Error>), Zbus(Result<(), zbus::Error>),
Theme(Theme),
} }
impl Application for Power { impl Application for Power {
@ -83,8 +84,12 @@ impl Application for Power {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Power, Command<Message>) { fn new(_flags: ()) -> (Power, Command<Message>) {
let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
( (
Power { Power {
applet_helper,
theme,
icon_name: "system-shutdown-symbolic".to_string(), icon_name: "system-shutdown-symbolic".to_string(),
..Default::default() ..Default::default()
}, },
@ -112,19 +117,26 @@ impl Application for Power {
} }
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
events_with(|e, _status| match e { Subscription::batch(vec![
cosmic::iced::Event::PlatformSpecific(PlatformSpecific::Wayland( self.applet_helper.theme_subscription(0).map(Message::Theme),
wayland::Event::Layer(LayerEvent::Unfocused, ..), events_with(|e, _status| match e {
)) => Some(Message::Cancel), cosmic::iced::Event::PlatformSpecific(PlatformSpecific::Wayland(
// cosmic::iced::Event::PlatformSpecific(PlatformSpecific::Wayland( wayland::Event::Layer(LayerEvent::Unfocused, ..),
// wayland::Event::Seat(wayland::SeatEvent::Leave, _), )) => Some(Message::Cancel),
// )) => Some(Message::Cancel), // cosmic::iced::Event::PlatformSpecific(PlatformSpecific::Wayland(
_ => None, // wayland::Event::Seat(wayland::SeatEvent::Leave, _),
}) // )) => Some(Message::Cancel),
_ => None,
}),
])
} }
fn update(&mut self, message: Message) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::Theme(t) => {
self.theme = t;
Command::none()
}
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)

View file

@ -71,6 +71,7 @@ enum Message {
Tick, Tick,
Ignore, Ignore,
Rectangle(RectangleUpdate<u32>), Rectangle(RectangleUpdate<u32>),
Theme(Theme),
} }
impl Application for Time { impl Application for Time {
@ -80,7 +81,16 @@ impl Application for Time {
type Flags = (); type Flags = ();
fn new(_flags: ()) -> (Time, Command<Message>) { fn new(_flags: ()) -> (Time, Command<Message>) {
(Time::default(), Command::none()) let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
(
Time {
applet_helper,
theme,
..Default::default()
},
Command::none(),
)
} }
fn title(&self) -> String { fn title(&self) -> String {
@ -118,6 +128,7 @@ impl Application for Time {
.expect("Setting nanoseconds to 0 should always be possible."); .expect("Setting nanoseconds to 0 should always be possible.");
let wait = 1.max((next - now).num_milliseconds()); let wait = 1.max((next - now).num_milliseconds());
Subscription::batch(vec![ Subscription::batch(vec![
self.applet_helper.theme_subscription(0).map(Message::Theme),
rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)), rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)),
time::every(Duration::from_millis( time::every(Duration::from_millis(
wait.try_into().unwrap_or(FALLBACK_DELAY), wait.try_into().unwrap_or(FALLBACK_DELAY),
@ -128,6 +139,10 @@ impl Application for Time {
fn update(&mut self, message: Message) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::Theme(t) => {
self.theme = t;
Command::none()
}
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)

View file

@ -52,6 +52,7 @@ enum Message {
WorkspaceUpdate(WorkspacesUpdate), WorkspaceUpdate(WorkspacesUpdate),
WorkspacePressed(ObjectId), WorkspacePressed(ObjectId),
WheelScrolled(ScrollDelta), WheelScrolled(ScrollDelta),
Theme(Theme),
Errored, Errored,
} }
@ -69,7 +70,7 @@ impl Application for IcedWorkspacesApplet {
PanelAnchor::Left | PanelAnchor::Right => Layout::Column, PanelAnchor::Left | PanelAnchor::Right => Layout::Column,
PanelAnchor::Top | PanelAnchor::Bottom => Layout::Row, PanelAnchor::Top | PanelAnchor::Bottom => Layout::Row,
}, },
theme: Default::default(), theme: applet_helper.theme(),
workspaces: Vec::new(), workspaces: Vec::new(),
workspace_tx: Default::default(), workspace_tx: Default::default(),
helper: Default::default(), helper: Default::default(),
@ -124,6 +125,7 @@ impl Application for IcedWorkspacesApplet {
} }
} }
Message::Errored => {} Message::Errored => {}
Message::Theme(t) => self.theme = t,
} }
Command::none() Command::none()
} }
@ -182,6 +184,7 @@ impl Application for IcedWorkspacesApplet {
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
Subscription::batch( Subscription::batch(
vec![ vec![
self.helper.theme_subscription(0).map(Message::Theme),
workspaces(0).map(|e| Message::WorkspaceUpdate(e.1)), workspaces(0).map(|e| Message::WorkspaceUpdate(e.1)),
subscription::events_with(|e, _| match e { subscription::events_with(|e, _| match e {
Mouse(mouse::Event::WheelScrolled { delta }) => { Mouse(mouse::Event::WheelScrolled { delta }) => {

View file

@ -3,6 +3,7 @@ use cosmic::{
iced::{self, wayland::InitialSurface, Application}, iced::{self, wayland::InitialSurface, Application},
iced_runtime::core::window, iced_runtime::core::window,
iced_style::application, iced_style::application,
theme::Theme,
}; };
use cosmic_applet::CosmicAppletHelper; use cosmic_applet::CosmicAppletHelper;
use freedesktop_desktop_entry::DesktopEntry; use freedesktop_desktop_entry::DesktopEntry;
@ -17,11 +18,14 @@ struct Desktop {
struct Button { struct Button {
desktop: Desktop, desktop: Desktop,
applet_helper: CosmicAppletHelper,
theme: Theme,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Msg { enum Msg {
Press, Press,
Theme(Theme),
} }
impl iced::Application for Button { impl iced::Application for Button {
@ -31,7 +35,16 @@ impl iced::Application for Button {
type Flags = Desktop; type Flags = Desktop;
fn new(desktop: Desktop) -> (Self, iced::Command<Msg>) { fn new(desktop: Desktop) -> (Self, iced::Command<Msg>) {
(Button { desktop }, iced::Command::none()) let applet_helper = CosmicAppletHelper::default();
let theme = applet_helper.theme();
(
Button {
desktop,
applet_helper,
theme,
},
iced::Command::none(),
)
} }
fn title(&self) -> String { fn title(&self) -> String {
@ -52,16 +65,19 @@ impl iced::Application for Button {
} }
fn subscription(&self) -> iced::Subscription<Msg> { fn subscription(&self) -> iced::Subscription<Msg> {
iced::Subscription::none() self.applet_helper.theme_subscription(0).map(Msg::Theme)
} }
fn update(&mut self, message: Msg) -> iced::Command<Msg> { fn update(&mut self, message: Msg) -> iced::Command<Msg> {
match message { match message {
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();
iced::Command::none() }
Msg::Theme(t) => {
self.theme = t;
} }
} }
iced::Command::none()
} }
fn view(&self, _id: window::Id) -> cosmic::Element<Msg> { fn view(&self, _id: window::Id) -> cosmic::Element<Msg> {