diff --git a/Cargo.lock b/Cargo.lock
index 687db0da..05ebb693 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -681,6 +681,14 @@ dependencies = [
"zvariant",
]
+[[package]]
+name = "cosmic-panel-button"
+version = "0.1.0"
+dependencies = [
+ "freedesktop-desktop-entry",
+ "libcosmic",
+]
+
[[package]]
name = "cosmic-panel-config"
version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
index 0ba094e4..5dbf38a8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ members = [
"cosmic-applet-power",
"cosmic-applet-time",
"cosmic-applet-workspaces",
+ "cosmic-panel-button",
]
[profile.release]
diff --git a/cosmic-applet-audio/data/resources/resources.gresource.xml b/cosmic-applet-audio/data/resources/resources.gresource.xml
deleted file mode 100644
index bdc8cdd8..00000000
--- a/cosmic-applet-audio/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/cosmic-applet-graphics/data/resources/resources.gresource.xml b/cosmic-applet-graphics/data/resources/resources.gresource.xml
deleted file mode 100644
index 2cf0970f..00000000
--- a/cosmic-applet-graphics/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/cosmic-applet-network/data/resources/resources.gresource.xml b/cosmic-applet-network/data/resources/resources.gresource.xml
deleted file mode 100644
index 2cf0970f..00000000
--- a/cosmic-applet-network/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/cosmic-applet-power/data/resources/resources.gresource.xml b/cosmic-applet-power/data/resources/resources.gresource.xml
deleted file mode 100644
index 2cf0970f..00000000
--- a/cosmic-applet-power/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/cosmic-applet-workspaces/data/resources/resources.gresource.xml b/cosmic-applet-workspaces/data/resources/resources.gresource.xml
deleted file mode 100644
index 8b69c0d6..00000000
--- a/cosmic-applet-workspaces/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- style.css
-
-
diff --git a/cosmic-applet-workspaces/data/resources/style.css b/cosmic-applet-workspaces/data/resources/style.css
deleted file mode 100644
index a1ed808f..00000000
--- a/cosmic-applet-workspaces/data/resources/style.css
+++ /dev/null
@@ -1,99 +0,0 @@
-button.alert {
- border-radius: 0;
- padding: 0px;
- background-color: @destructive_color;
- background-image: none;
- color: @destructive_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-button.active {
- border-radius: 0;
- padding: 0px;
- background-color: @accent_color;
- background-image: none;
- color: @accent_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-button.inactive {
- border-radius: 0;
- padding: 0px;
- background-color: @view_bg_color;
- background-image: none;
- color: @view_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-button.alert:hover {
- border-radius: 0;
- padding: 0px;
- background-color: darker(@destructive_color);
- background-image: none;
- color: @destructive_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-button.active:hover {
- border-radius: 0;
- padding: 0px;
- background-color: darker(@accent_color);
- background-image: none;
- color: @accent_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-button.inactive:hover {
- border-radius: 0;
- padding: 0px;
- background-color: darker(@view_bg_color);
- background-image: none;
- color: @view_fg_color;
- border-color: transparent;
- outline-color: transparent;
-}
-
-window {
- background: transparent;
-}
-
-listview {
- border-color: transparent;
- background: transparent;
- outline-color: transparent;
-}
-
-listview row {
- padding-left: 0px;
- padding-right: 0px;
- padding-top: 0px;
- padding-bottom: 0px;
- background: transparent;
- border-color: transparent;
- outline-color: transparent;
-}
-
-listview row:hover {
- padding-left: 0px;
- padding-right: 0px;
- padding-top: 0px;
- padding-bottom: 0px;
- background: transparent;
- border-color: transparent;
- outline-color: transparent;
-}
-
-label {
- padding: 0px;
- background-color: transparent;
-}
-
-box {
- padding: 0px;
- background-color: transparent;
-}
\ No newline at end of file
diff --git a/cosmic-panel-app-button/data/com.system76.CosmicPanelAppButton.desktop b/cosmic-panel-app-button/data/com.system76.CosmicPanelAppButton.desktop
index f8963af1..edecafb9 100644
--- a/cosmic-panel-app-button/data/com.system76.CosmicPanelAppButton.desktop
+++ b/cosmic-panel-app-button/data/com.system76.CosmicPanelAppButton.desktop
@@ -2,7 +2,7 @@
Name=Cosmic Panel App Library Button
Comment=Write a GTK + Rust application
Type=Application
-Exec=cosmic-panel-button --id com.system76.CosmicAppLibrary
+Exec=cosmic-panel-button com.system76.CosmicAppLibrary
Terminal=false
Categories=GNOME;GTK;
Keywords=Gnome;GTK;
diff --git a/cosmic-panel-app-button/data/resources/resources.gresource.xml b/cosmic-panel-app-button/data/resources/resources.gresource.xml
deleted file mode 100644
index 3e8c922d..00000000
--- a/cosmic-panel-app-button/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/cosmic-panel-button/Cargo.toml b/cosmic-panel-button/Cargo.toml
new file mode 100644
index 00000000..3095b77c
--- /dev/null
+++ b/cosmic-panel-button/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "cosmic-panel-button"
+version = "0.1.0"
+edition = "2021"
+license = "GPL-3.0-or-later"
+
+[dependencies]
+freedesktop-desktop-entry = "0.5.0"
+libcosmic = { git = "https://github.com/pop-os/libcosmic/", branch = "master", default-features = false, features = ["tokio", "wayland", "applet"] }
diff --git a/cosmic-panel-button/src/main.rs b/cosmic-panel-button/src/main.rs
new file mode 100644
index 00000000..ee7570f6
--- /dev/null
+++ b/cosmic-panel-button/src/main.rs
@@ -0,0 +1,122 @@
+use cosmic::{
+ applet::CosmicAppletHelper,
+ iced::{
+ self,
+ wayland::{InitialSurface, SurfaceIdWrapper},
+ Application,
+ },
+ iced_sctk::layout::Limits,
+ iced_style::application,
+};
+use freedesktop_desktop_entry::DesktopEntry;
+use std::{env, fs, process::Command};
+
+#[derive(Clone, Default)]
+struct Desktop {
+ name: String,
+ icon: Option,
+ exec: String,
+}
+
+struct Button {
+ desktop: Desktop,
+}
+
+#[derive(Debug, Clone)]
+enum Msg {
+ Press,
+}
+
+impl iced::Application for Button {
+ type Message = Msg;
+ type Theme = cosmic::Theme;
+ type Executor = cosmic::SingleThreadExecutor;
+ type Flags = Desktop;
+
+ fn new(desktop: Desktop) -> (Self, iced::Command) {
+ (Button { desktop }, iced::Command::none())
+ }
+
+ fn title(&self) -> String {
+ String::from("Button")
+ }
+
+ fn close_requested(&self, _id: SurfaceIdWrapper) -> Msg {
+ unimplemented!()
+ }
+
+ fn style(&self) -> ::Style {
+ ::Style::Custom(|theme| application::Appearance {
+ background_color: iced::Color::from_rgba(0.0, 0.0, 0.0, 0.0),
+ text_color: theme.cosmic().on_bg_color().into(),
+ })
+ }
+
+ fn subscription(&self) -> iced::Subscription {
+ iced::Subscription::none()
+ }
+
+ fn update(&mut self, message: Msg) -> iced::Command {
+ match message {
+ Msg::Press => {
+ let _ = Command::new("sh").arg("-c").arg(&self.desktop.exec).spawn();
+ iced::Command::none()
+ }
+ }
+ }
+
+ fn view(&self, _id: SurfaceIdWrapper) -> cosmic::Element {
+ // TODO icon?
+ cosmic::widget::button(cosmic::theme::Button::Text)
+ .text(&self.desktop.name)
+ .on_press(Msg::Press)
+ .into()
+ }
+}
+
+pub fn main() -> iced::Result {
+ let id = env::args()
+ .skip(1)
+ .next()
+ .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() {
+ path.push(&filename);
+ if let Ok(bytes) = fs::read_to_string(&path) {
+ if let Ok(entry) = DesktopEntry::decode(&path, &bytes) {
+ desktop = Some(Desktop {
+ name: entry
+ .name(None)
+ .map(|x| x.to_string())
+ .expect(&format!("Desktop file '{filename}' doesn't have `Name`")),
+ icon: entry.icon().map(|x| x.to_string()),
+ exec: entry
+ .exec()
+ .map(|x| x.to_string())
+ .expect(&format!("Desktop file '{filename}' doesn't have `Exec`")),
+ });
+ break;
+ }
+ }
+ }
+ let desktop = desktop.expect(&format!(
+ "Failed to find valid desktop file '{filename}' in search paths"
+ ));
+ let helper = CosmicAppletHelper::default();
+ let mut settings = iced::Settings {
+ flags: desktop,
+ ..helper.window_settings()
+ };
+ match &mut settings.initial_surface {
+ InitialSurface::XdgWindow(s) => {
+ s.iced_settings.min_size = Some((1, 1));
+ s.iced_settings.max_size = None;
+ s.autosize = true;
+ s.size_limits = Limits::NONE.min_height(1).min_width(1);
+ }
+ _ => unreachable!(),
+ };
+ Button::run(settings)
+}
diff --git a/cosmic-panel-workspaces-button/data/com.system76.CosmicPanelWorkspacesButton.desktop b/cosmic-panel-workspaces-button/data/com.system76.CosmicPanelWorkspacesButton.desktop
index 3d929b81..3ab49ae1 100644
--- a/cosmic-panel-workspaces-button/data/com.system76.CosmicPanelWorkspacesButton.desktop
+++ b/cosmic-panel-workspaces-button/data/com.system76.CosmicPanelWorkspacesButton.desktop
@@ -2,7 +2,7 @@
Name=Cosmic Panel Workspaces Button
Comment=Write a GTK + Rust application
Type=Application
-Exec=cosmic-panel-button -id com.system76.CosmicWorkspaces
+Exec=cosmic-panel-button com.system76.CosmicWorkspaces
Terminal=false
Categories=GNOME;GTK;
Keywords=Gnome;GTK;
diff --git a/cosmic-panel-workspaces-button/data/resources/resources.gresource.xml b/cosmic-panel-workspaces-button/data/resources/resources.gresource.xml
deleted file mode 100644
index 3e8c922d..00000000
--- a/cosmic-panel-workspaces-button/data/resources/resources.gresource.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/justfile b/justfile
index 7ce412dd..1ef63322 100644
--- a/justfile
+++ b/justfile
@@ -39,12 +39,14 @@ _install_power: (_install 'com.system76.CosmicAppletPower' 'cosmic-applet-power'
_install_workspace: (_install 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces')
_install_time: (_install 'com.system76.CosmicAppletTime' 'cosmic-applet-time')
-# TODO: `cosmic-panel-button` no longer exists and hasn't been ported to Iced
-# _install_app_button: (_install 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button')
-# _install_workspaces_button: (_install 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')
+# TODO: Turn this into one configurable applet?
+_install_panel_button: (_install_bin 'cosmic-panel-button')
+_install_button id name: (_install_icon name + '/data/icons/' + id + '.svg') (_install_desktop name + '/data/' + id + '.desktop')
+_install_app_button: (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button')
+_install_workspaces_button: (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')
# Installs files into the system
-install: _install_app_list _install_audio _install_battery _install_bluetooth _install_graphics _install_network _install_notifications _install_power _install_workspace _install_time
+install: _install_app_list _install_audio _install_battery _install_bluetooth _install_graphics _install_network _install_notifications _install_power _install_workspace _install_time _install_panel_button _install_app_button _install_workspaces_button
# Extracts vendored dependencies if vendor=1
_extract_vendor: